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.
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]
}
| Pole | Wymagane | Opis |
|---|---|---|
first_name, last_name | tak | Imię i nazwisko osoby zakładającej konto. |
email | tak | Unikalny adres e-mail merchanta. |
phone | tak | Polski numer telefonu: dokładnie 9 cyfr. |
partner_external_ref | tak | Twój identyfikator merchanta (ref w dalszych wywołaniach). Do 128 znaków URL-safe. |
consents | tak | Identyfikatory zaakceptowanych definicji zgód (otrzymasz je od dpay dla swojego kanału). |
channel | warunkowo | Wymagany 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"
}
| Pole | Wymagane | Opis |
|---|---|---|
account_number | tak | Polski IBAN: PL + 26 cyfr (walidowana suma kontrolna). |
url_address | tak | Adres strony / sklepu merchanta. |
turnover | tak | Szacowany miesięczny obrót (liczba całkowita, w złotych). |
avg_transaction_value | tak | Średnia wartość transakcji. |
monthly_transactions | tak | Szacowana liczba transakcji miesięcznie. |
relationship_purpose | tak | Potwierdzenie celu nawiązania współpracy (true). |
shop_industry_id | tak | Branża sklepu ze słownika dpay; przy branży "Inne" dodatkowo shop_industry_description. |
main_activity_code | dla firm | Głó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), zdocument_type(np. pełnomocnictwo, dokument tożsamości) isubject, albo z identyfikatorem dokumentu działalności regulowanej. Odpowiedź zawieradocument_id- zachowaj go, aby dołączyć pełnomocnictwo do zaproszenia reprezentanta-pełnomocnika. Duplikat dokumentu regulowanego zwraca409. - 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 przezDELETE /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), opcjonalnieexternal_ref(idempotencja - powtórka nie wyśle drugiego SMS-a) ipower_of_attorney_document_id(wymagany dla pełnomocnika). Zaproszona osoba dostaje własny link do hostowanego flow (hosted_url). Odpowiedzi i listaGET /invitationssą wolne od danych osobowych zaproszonego. Dostępne też:POST /invitations/{id}/resend(ponowna wysyłka e-mail + SMS, cooldown - zbyt szybka powtórka zwraca429) iDELETE /invitations/{id}(anulowanie - link przestaje działać).
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.urlto hostowany adres wznowienia: loguje merchanta (tokenem w ścieżce) i przenosi go do właściwego kroku.next_action.embeddablemówi, czy możesz osadzić ten adres w iframe:true, gdy Twoja domena jest zarejestrowana do osadzania. Przyfalseprzekieruj merchanta nanext_action.urlna najwyższym poziomie okna.missingto lista kodów braków danych. Pusta lista oznacza komplet danych - merchant nadal musi wykonać akty osobiste podnext_action.url.
Kody braków (missing[])
| Kod | Znaczenie |
|---|---|
account_type.missing | Nie wybrano typu podmiotu (najpierw PATCH /company). |
company.nip_missing | Brak NIP / danych rejestrowych firmy. |
bank.account_missing | Brak rachunku / profilu transakcyjnego. |
identity.pesel_missing | Brak tożsamości głównego wnioskodawcy (osoba fizyczna / JDG). |
representation.required | Brak decyzji o reprezentacji (spółka wieloosobowa). |
beneficiaries.required | Brak beneficjenta rzeczywistego i brak oczekującego zaproszenia. |
documents.required | Zaległ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 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.
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
| Kod | Znaczenie |
|---|---|
401 | Brak / nieprawidłowy / cofnięty klucz partnera. |
403 | Klucz nie ma wymaganego scope. |
404 | Nieznany ref w Twoich kanałach. |
409 | Onboarding już aktywny - dane nie są już edytowalne (lub duplikat dokumentu regulowanego). |
410 | Link wznowienia wygasł lub konto jest już aktywne (trasa hostowana). |
422 | Błąd walidacji albo segment nie dotyczy tego typu podmiotu. |
429 | Cooldown ponownej wysyłki zaproszenia. |