Przejdź do głównej zawartości

Onboarding przez API (headless)

Tryb dla partnerów, którzy chcą pełną kontrolę nad UI. Zbierasz dane merchanta we własnym interfejsie i wysyłasz je do dpay segmentami przez API. Akty, które prawnie musi wykonać sama osoba (weryfikacja kontaktu i tożsamości, oświadczenia, podpis umowy, przelew weryfikacyjny), realizuje merchant w krótkim hostowanym hand-offie dpay.

Model hybrydowy

Dane strukturalne (firma, rachunek, beneficjenci, dokumenty) wysyłasz przez API i renderujesz we własnym UI. Akty osobiste (weryfikacja tożsamości, oświadczenia PEP, podpis umowy) zostają hostowane przez dpay - to wymóg bezpieczeństwa i zgodności, którego nie da się przenieść do Twojego UI.

Cały przepływ

Krok 1: utwórz draft

Draft wymaga danych kontaktowych osoby zakładającej konto i zaakceptowanych zgód:

POST https://panel.dpay.pl/api/partner/v1/onboarding
Authorization: Bearer dpk_twoj_klucz_platformy
Content-Type: application/json

{
"first_name": "Jan",
"last_name": "Kowalski",
"email": "jan.kowalski@example.com",
"phone": "601234567",
"partner_external_ref": "faktura-klient-123",
"consents": [1, 2, 3]
}
PoleWymaganeOpis
first_name, last_nametakImię i nazwisko osoby zakładającej konto.
emailtakUnikalny adres e-mail merchanta.
phonetakPolski numer telefonu: dokładnie 9 cyfr.
partner_external_reftakTwój identyfikator merchanta (ref w dalszych wywołaniach). Do 128 znaków URL-safe.
consentstakIdentyfikatory zaakceptowanych definicji zgód (otrzymasz je od dpay dla swojego kanału).
channelwarunkowoWymagany tylko, gdy Twój klucz ma więcej niż jeden kanał.

Odpowiedź (201, lub 200 gdy draft dla tego ref już istnieje):

{
"id": 12345,
"ref": "faktura-klient-123",
"status": "started",
"channel": "fakturka"
}

Utworzenie draftu jest idempotentne: powtórne POST /onboarding z tym samym partner_external_ref zwróci istniejący draft (200), nie utworzy duplikatu. Odpowiedź nie zawiera adresu hostowanego flow - dostaniesz go z finalize lub GET /onboarding/{ref} w polu next_action.url.

Krok 2: wyślij dane segmentami

Uzupełniasz draft niezależnymi segmentami. Każdy segment możesz wysłać osobno i wielokrotnie (nadpisuje poprzednią wartość).

Dane firmy

Najpierw rozstrzygasz typ podmiotu flagą has_nip. Dla osoby fizycznej wysyłasz tylko has_nip: false. Dla firmy - NIP i dane rejestrowe:

PATCH https://panel.dpay.pl/api/partner/v1/onboarding/faktura-klient-123/company
Authorization: Bearer dpk_twoj_klucz_platformy
Content-Type: application/json

{
"has_nip": true,
"nip": "5270000000",
"company_name": "Przyklad Sp. z o.o.",
"registration_type": 1,
"street": "Przykladowa",
"street_number": "12",
"apartment_number": null,
"postal_code": "00-001",
"city": "Warszawa",
"country_code": "PL"
}

Wymagane dla firmy: has_nip, nip (10 cyfr, walidowana suma kontrolna), company_name, registration_type (forma prawna wg słownika dpay, np. 0 = JDG, 1 = sp. z o.o.), street, street_number, postal_code (format 00-000), city, country_code (2 litery). Opcjonalnie osobny adres korespondencyjny (company_has_other_correspondence_address + pola company_correspondence_*). Po podaniu NIP dpay pobiera dane z rejestrów publicznych; podmiot wykreślony z rejestru zwraca 422.

Rachunek bankowy i profil transakcyjny

Rachunek, na który merchant będzie otrzymywał rozliczenia i wypłaty, wraz z profilem działalności wymaganym przez przepisy AML. Segment wymaga wcześniejszego ustalenia typu podmiotu (PATCH /company).

PATCH https://panel.dpay.pl/api/partner/v1/onboarding/faktura-klient-123/bank-account
Authorization: Bearer dpk_twoj_klucz_platformy
Content-Type: application/json

{
"account_number": "PL61109010140000071219812874",
"url_address": "https://sklep-merchanta.pl",
"turnover": 50000,
"avg_transaction_value": 150,
"monthly_transactions": 300,
"relationship_purpose": true,
"shop_industry_id": 7,
"main_activity_code": "62.01.Z"
}
PoleWymaganeOpis
account_numbertakPolski IBAN: PL + 26 cyfr (walidowana suma kontrolna).
url_addresstakAdres strony / sklepu merchanta.
turnovertakSzacowany miesięczny obrót (liczba całkowita, w złotych).
avg_transaction_valuetakŚrednia wartość transakcji.
monthly_transactionstakSzacowana liczba transakcji miesięcznie.
relationship_purposetakPotwierdzenie celu nawiązania współpracy (true).
shop_industry_idtakBranża sklepu ze słownika dpay; przy branży "Inne" dodatkowo shop_industry_description.
main_activity_codedla firmGłówny kod PKD (z listy kodów podmiotu, format 00.00.X).

Dane tożsamości i reprezentacji

PATCH https://panel.dpay.pl/api/partner/v1/onboarding/faktura-klient-123/identity

Prefill tożsamości głównego wnioskodawcy (PESEL, dokument, adres, obywatelstwo). Dotyczy osoby fizycznej lub właściciela JDG; w spółce wieloosobowej tożsamość reprezentanta ustalana jest w hostowanym flow (ten segment zwróci wtedy 422). Sama weryfikacja tożsamości i oświadczenia PEP zawsze zostają w hand-offie.

PATCH https://panel.dpay.pl/api/partner/v1/onboarding/faktura-klient-123/representation

Tylko spółki wieloosobowe (422 w pozostałych przypadkach). Body: is_representative (bool - czy osoba zakładająca konto jest reprezentantem). Odpowiedź zawiera representation_mode (solo / co_representative / proxy) i flagę requires_invitation_or_poa.

Dokumenty, beneficjenci, zaproszenia

POST https://panel.dpay.pl/api/partner/v1/onboarding/faktura-klient-123/documents
POST https://panel.dpay.pl/api/partner/v1/onboarding/faktura-klient-123/beneficiaries
POST https://panel.dpay.pl/api/partner/v1/onboarding/faktura-klient-123/invitations
  • documents - plik przesyłasz jako multipart (file) albo base64 (content_base64 + filename), z document_type (np. pełnomocnictwo, dokument tożsamości) i subject, albo z identyfikatorem dokumentu działalności regulowanej. Odpowiedź zawiera document_id - zachowaj go, aby dołączyć pełnomocnictwo do zaproszenia reprezentanta-pełnomocnika. Duplikat dokumentu regulowanego zwraca 409.
  • beneficiaries - beneficjenci rzeczywiści (spółki wieloosobowe): tożsamość + adres + dokument + oświadczenia PEP i źródła majątku. Odpowiedź zawiera beneficiary_uuid; wpis usuniesz przez DELETE /onboarding/{ref}/beneficiaries/{uuid}.
  • invitations - jeśli akty osobiste ma dokończyć inna osoba (np. członek zarządu lub beneficjent), zapraszasz ją: role (representative / beneficial_owner), imię, nazwisko, e-mail, telefon (9 cyfr), opcjonalnie external_ref (idempotencja - powtórka nie wyśle drugiego SMS-a) i power_of_attorney_document_id (wymagany dla pełnomocnika). Zaproszona osoba dostaje własny link do hostowanego flow (hosted_url). Odpowiedzi i lista GET /invitations są wolne od danych osobowych zaproszonego. Dostępne też: POST /invitations/{id}/resend (ponowna wysyłka e-mail + SMS, cooldown - zbyt szybka powtórka zwraca 429) i DELETE /invitations/{id} (anulowanie - link przestaje działać).
Prefill z rejestrów

Nie musisz zbierać wszystkiego ręcznie. Po podaniu NIP dpay potrafi uzupełnić dane firmy i beneficjentów z rejestrów publicznych. W praktyce często wystarczy wysłać NIP i rachunek, a resztę merchant tylko potwierdza w hand-offie.

Krok 3: finalize

Gdy komplet danych jest wysłany, wywołujesz finalize. To operacja tylko do odczytu: sprawdza kompletność danych i zwraca hostowany hand-off - zawsze z kodem 200, także gdy czegoś brakuje.

POST https://panel.dpay.pl/api/partner/v1/onboarding/faktura-klient-123/finalize
Authorization: Bearer dpk_twoj_klucz_platformy

Odpowiedź:

{
"id": 12345,
"ref": "faktura-klient-123",
"channel": "fakturka",
"status": "in_progress",
"next_action": {
"type": "continue_onboarding",
"status": "in_progress",
"url": "https://panel.dpay.pl/onboarding-v3/continue/{token}",
"embeddable": true
},
"missing": ["bank.account_missing", "documents.required"]
}
  • next_action.url to hostowany adres wznowienia: loguje merchanta (tokenem w ścieżce) i przenosi go do właściwego kroku.
  • next_action.embeddable mówi, czy możesz osadzić ten adres w iframe: true, gdy Twoja domena jest zarejestrowana do osadzania. Przy false przekieruj merchanta na next_action.url na najwyższym poziomie okna.
  • missing to lista kodów braków danych. Pusta lista oznacza komplet danych - merchant nadal musi wykonać akty osobiste pod next_action.url.

Kody braków (missing[])

KodZnaczenie
account_type.missingNie wybrano typu podmiotu (najpierw PATCH /company).
company.nip_missingBrak NIP / danych rejestrowych firmy.
bank.account_missingBrak rachunku / profilu transakcyjnego.
identity.pesel_missingBrak tożsamości głównego wnioskodawcy (osoba fizyczna / JDG).
representation.requiredBrak decyzji o reprezentacji (spółka wieloosobowa).
beneficiaries.requiredBrak beneficjenta rzeczywistego i brak oczekującego zaproszenia.
documents.requiredZaległe dokumenty (w tym bazowe dokumenty firmowe).

Krok 4: hand-off aktów osobistych

Przekieruj merchanta na next_action.url (albo osadź go przez SDK), aby dokończył akty, których nie da się wykonać przez API:

  • weryfikacja kontaktu (kody SMS + e-mail),
  • weryfikacja tożsamości,
  • oświadczenia (m.in. PEP),
  • podpis umowy (kod SMS),
  • przelew weryfikacyjny.

Po każdej zmianie statusu dostajesz webhook.

Wznawianie i osadzanie (token wznowienia)

Token wznowienia to ostatni segment ścieżki next_action.url (48 znaków, bez przedrostka). Możesz osadzić hand-off w swojej stronie przez SDK:

<script src="https://panel.dpay.pl/sdk/dpay-onboarding-sdk.js"></script>
<script>
DpayOnboarding.mountResume('#dpay-onboarding', {
token: '<token z next_action.url>',
ref: 'faktura-klient-123',
onEvent: function (e) { /* { type, payload } */ },
});
</script>

Katalog zdarzeń i pozostałe opcje opisuje onboarding przez iframe. Jeśli next_action.embeddable jest false, zamiast osadzać przekieruj merchanta na next_action.url.

Token wznowienia jest wrażliwy i ograniczony czasowo

Token daje dostęp do dokończenia onboardingu tego merchanta - traktuj go jak sekret (nie loguj, nie osadzaj w URL współdzielonych). Link jest ważny 45 dni i przestaje działać po aktywacji konta - w obu przypadkach zwraca 410 Gone. Powtórny POST /onboarding z tym samym ref zwraca istniejący draft bez wymiany tokenu - po wygaśnięciu linku skontaktuj się z dpay.

Status onboardingu

Status pojedynczego onboardingu odczytasz w każdej chwili:

GET https://panel.dpay.pl/api/partner/v1/onboarding/faktura-klient-123
Authorization: Bearer dpk_twoj_klucz_platformy
{
"id": 12345,
"ref": "faktura-klient-123",
"channel": "fakturka",
"status": "completed",
"next_action": {
"type": "continue_onboarding",
"status": "completed",
"url": "https://panel.dpay.pl/onboarding-v3/continue/{token}",
"embeddable": true
},
"invited": []
}

next_action jest zawsze obiektem (jego url może być null), a invited to lista zaproszeń (bez danych osobowych zaproszonych). Listę wszystkich onboardingów Twojego kanału zwraca GET /onboarding (paginacja kursorowa: per_page do 200 i cursor). Znaczenie statusów opisuje cykl życia konta.

Źródło prawdy

Do reakcji na zmiany używaj webhooków (push), a GET /onboarding/{ref} traktuj jako uzupełniające sprawdzenie (pull). Nie odpytuj statusu w pętli co sekundę.

Kody błędów

KodZnaczenie
401Brak / nieprawidłowy / cofnięty klucz partnera.
403Klucz nie ma wymaganego scope.
404Nieznany ref w Twoich kanałach.
409Onboarding już aktywny - dane nie są już edytowalne (lub duplikat dokumentu regulowanego).
410Link wznowienia wygasł lub konto jest już aktywne (trasa hostowana).
422Błąd walidacji albo segment nie dotyczy tego typu podmiotu.
429Cooldown ponownej wysyłki zaproszenia.