Przejdź do treści
InvoiceIQ Faktury i KSeF

Publiczne API v0.3.0-preview.1 · OpenAPI 3.1.2

Quickstart

Najpierw utwórz klienta w panelu organizacji. Zapisz jednorazowo pokazany sekret w secret managerze; InvoiceIQ nie pokaże go ponownie.

1. Machine-to-machine

Utwórz klienta typu M2M wyłącznie ze scope’em customers:read. Poniższy smoke test używa rzeczywistej operacji, nie testowego endpointu.

export INVOICEIQ_BASE_URL='https://twoj-issuer.example'
export INVOICEIQ_CLIENT_ID='identyfikator-z-panelu'
read -r -s -p 'Client secret: ' INVOICEIQ_CLIENT_SECRET

TOKEN_RESPONSE="$({
  printf 'user = "%s:%s"\n' "$INVOICEIQ_CLIENT_ID" "$INVOICEIQ_CLIENT_SECRET"
  printf 'data = "grant_type=client_credentials"\n'
  printf 'data = "scope=customers:read"\n'
} | curl --silent --show-error --fail-with-body --config - \
    "$INVOICEIQ_BASE_URL/oauth/token")"
unset INVOICEIQ_CLIENT_SECRET
ACCESS_TOKEN="$(printf '%s' "$TOKEN_RESPONSE" | jq -er '.access_token')"

printf 'header = "Authorization: Bearer %s"\n' "$ACCESS_TOKEN" |
  curl --silent --show-error --fail-with-body --config - \
    "$INVOICEIQ_BASE_URL/api/v1/customers"
unset ACCESS_TOKEN TOKEN_RESPONSE

HTTP Basic jest profilem zalecanym. Runtime Passport akceptuje również client_secret_post, ale quickstart nie umieszcza sekretu w body, URL ani committed pliku.

2. Delegated authorization

Utwórz poufnego klienta delegated z dokładnym HTTPS redirect URI i ustaw zmienne bazowego URL/client ID na jego wartości. Przechowuj state i verifier po stronie backendu konsumenta, powiązane z jego sesją.

STATE="$(openssl rand -hex 32)"
VERIFIER="$(openssl rand -base64 96 | tr '+/' '-_' | tr -d '=\n' | cut -c1-96)"
CHALLENGE="$(printf '%s' "$VERIFIER" | openssl dgst -binary -sha256 | openssl base64 -A | tr '+/' '-_' | tr -d '=')"

export STATE VERIFIER CHALLENGE
export INVOICEIQ_REDIRECT_URI='https://consumer.example/oauth/callback'
AUTH_URL="$(php -r '
  echo getenv("INVOICEIQ_BASE_URL")."/oauth/authorize?".http_build_query([
    "response_type" => "code",
    "client_id" => getenv("INVOICEIQ_CLIENT_ID"),
    "redirect_uri" => getenv("INVOICEIQ_REDIRECT_URI"),
    "scope" => "customers:read",
    "state" => getenv("STATE"),
    "code_challenge" => getenv("CHALLENGE"),
    "code_challenge_method" => "S256",
  ]);
')"
printf 'Otwórz w przeglądarce: %s\n' "$AUTH_URL"

# Backend callbacku musi przerwać flow, jeżeli zwrócone state != $STATE.
read -r -p 'Authorization code po sprawdzeniu state: ' AUTHORIZATION_CODE
read -r -s -p 'Client secret: ' INVOICEIQ_CLIENT_SECRET

TOKEN_RESPONSE="$({
  printf 'user = "%s:%s"\n' "$INVOICEIQ_CLIENT_ID" "$INVOICEIQ_CLIENT_SECRET"
  printf 'data-urlencode = "grant_type=authorization_code"\n'
  printf 'data-urlencode = "redirect_uri=%s"\n' "$INVOICEIQ_REDIRECT_URI"
  printf 'data-urlencode = "code=%s"\n' "$AUTHORIZATION_CODE"
  printf 'data-urlencode = "code_verifier=%s"\n' "$VERIFIER"
} | curl --silent --show-error --fail-with-body --config - \
    "$INVOICEIQ_BASE_URL/oauth/token")"
unset INVOICEIQ_CLIENT_SECRET AUTHORIZATION_CODE VERIFIER CHALLENGE STATE AUTH_URL

InvoiceIQ wymaga zalogowanej, zweryfikowanej przez MFA osoby, aktywnego członkostwa oraz ekranu consent. Po callbacku konsument najpierw porównuje zwrócone state stałoczasowo. Przy mismatch kończy przepływ bez wymiany kodu. Kod, redirect URI i code_verifier są następnie wysyłane do /oauth/token, a poufny klient nadal uwierzytelnia się przez HTTP Basic.

Laravel Passport reklamuje plain, S256 i akceptuje S256, ale nie wymusza PKCE na poufnym kliencie. Konsument ma zawsze wysyłać i sprawdzać S256; nie traktuj braku serwerowego wymuszenia jako obniżenia wymagań klienta.

3. Mutacje i procesy asynchroniczne