Przejdź do głównej zawartości

Zwroty

Płatność może zostać zwrócona wielokrotnie na łączną kwotę nieprzekraczającą kwoty płatności i jest to dozwolone tylko w przypadku płatności w statusie CONFIRMED. Paynow akceptuje zwroty z minimalną kwotą 1 PLN dla płatności kartą a dla innych metod 0,01 PLN.

Uwaga

Aby móc dokonać standardowego zwrotu za pomocą API, Twój sklep musi mieć włączoną opcję „dziennie” w Harmonogramie wypłat dla danego sklepu. Środki potrzebne do dokonania zwrotu zostaną pobrane z Twojego salda.

Jeśli na Twoim saldzie nie ma wystarczających środków na wykonanie zwrotu (np. Twój sklep ma mało sprzedaży lub nie miał ich w ostatnim czasie), możesz skorzystać ze zwrotu przelewem. Taki zwrot nie jest pobierany z Twojego salda – jest finansowany dedykowanym przelewem bankowym wykonanym na potrzeby tego konkretnego zwrotu.

Możesz również otrzymywać powiadomienia, gdy zwrot osiągnie status końcowy.

Zwroty oczekujące - opcjonalne​

Zwrot oczekujący to specjalny rodzaj zwrotu, który można zainicjować nawet jeśli kwota zwrotu przekracza saldo. Po zainicjowaniu taki zwrot będzie miał status NEW. Po zgromadzeniu wystarczającej ilości środków na saldzie zwroty zostaną przetworzone przy użyciu algorytmu FIFO (co oznacza, że zwroty są przetwarzane w kolejności, w jakiej zostały zainicjowane).

Jeśli nie zgromadzisz wymaganych środków na zwrot na saldzie przez 120 godzin (5 dni, wartość domyślna), status zwrotu zmieni się na CANCELLED.

Możesz zmienić czas, po którym zwroty oczekujące zostaną anulowane - jednostką tego parametru jest godzina.

Aby włączyć tę funkcję w swoim sklepie i/lub zmienić domyślny czas anulowania zwrotu oczekującego (opcjonalnie), przejdź do zakładki Ustawienia > Zwroty oczekujące w Panelu Merchanta.

Zwrot oczekujący czy zwrot przelewem?

Zwrot oczekujący czeka na zgromadzenie środków z przyszłej sprzedaży na Twoim saldzie. Zwrot przelewem w ogóle nie korzysta z Twojego salda – jest finansowany przelewem bankowym wykonanym dla tego konkretnego zwrotu. Użyj go, gdy nie spodziewasz się wystarczającej sprzedaży, aby pokryć zwrot na czas.

Diagram procesu zwrotu​

Poniższy diagram sekwencji przedstawia proces zwrotu zakończony sukcesem:

business flow image

Mapa statusów zwrotu​

Na poniższym obrazku przedstawiono wszystkie statusy, jakie może przyjąć zwrot, oraz możliwe przejścia między nimi:

business flow image

Wyjaśnienie:

CodeDescription
NEWZwrot został zaakceptowany.
PENDINGPaynow rozpoczyna przetwarzanie żądania zwrotu.
SUCCESSFULZwrot został pomyślnie przetworzony przez Paynow, a pieniądze zostały przelane na konto kupującego.
FAILEDWystąpił problem podczas przetwarzania zwrotu. Pieniądze nie zostały przelane na rzecz kupującego.
CANCELLEDZwrot został anulowany. Pieniądze nie zostały przelane na rzecz kupującego. Anulować można tylko zwroty o statusie NEW.

Utwórz zwrot​

Na potrzeby tego przewodnika przyjmiemy założenie, że dane autoryzacyjne to:

  • Api-Key = 97a55694-5478-43b5-b406-fb49ebfdd2b5
  • Signature-Key = b305b996-bca5-4404-a0b7-2ccea3d2b64b

Załóżmy również, że paymentId to NOR3-FUN-D4U-LOL

Krok 1: Przygotuj wiadomość z żądanien zwrotu. W tym przykładzie użyjemy prostej wiadomości zawierającej tylko wymagane pola, które wyglądają następująco:

{
"amount": 100,
"reason": "RMA"
}

Podana kwota powinna być podana w najmniejszej jednostce waluty zwrotu (grosz w przypadku PLN). Oznacza to, że powyższe żądanie definiuje zwrot w wysokości 1,00 PLN. Pole opisu powinno zawierać powód zwrotu. Pełną specyfikację wiadomości żądania zwrotu można znaleźć poniżej

Opcjonalnie możesz dodać pole notificationUrl. Jeśli zostanie podane, Paynow wyśle powiadomienie na ten adres, gdy zwrot osiągnie status końcowy. Zobacz Powiadomienia o statusie zwrotu.

{
"amount": 100,
"reason": "RMA",
"notificationUrl": "https://shop.example.com/paynow/refund-notifications"
}

Krok 2: Dołącz nagłówek Api-Key z wartością Api-Key, którą znajdziesz w Panelu Merchanta.

Krok 3: Oblicz podpis i dołącz go jako nagłówek Signature. Dla podanego przykładu prawidłowy podpis to o5HQfxngBqr68sLOEtJu0fd1Cl/GzfehZEswk6KMb0w=

Ważne

Jeśli próbujesz obliczyć podpis z przykładu w swoim kodzie i otrzymujesz inny wynik, upewnij się, że Twoja wiadomość JSON jest sformatowana w ten sam sposób, co wiadomość w przykładzie, tj. z wcięciem czterech spacji i bez znaku nowej linii na końcu.

Krok 4: Wygeneruj losowy ciąg o maksymalnej długości 45 znaków dla nagłówka Idempotency-Key.

Krok 5: Wykonaj żądanie POST z przygotowaną wiadomością na endpoint żądania zwrotu

curl --location 'https://api.sandbox.paynow.pl/v3/payments/NOM3-VWX-YS7-J43/refunds' \
--header 'Api-Key: 97a55694-5478-43b5-b406-fb49ebfdd2b5' \
--header 'Signature: o5HQfxngBqr68sLOEtJu0fd1Cl/GzfehZEswk6KMb0w=' \
--header 'Content-Type: application/json' \
--data '{
"amount": 100
}'
Uwaga

Pamiętaj, że żądanie musi zawierać nagłówki Host i Accept jak opisano tutaj. Nie są one wymienione powyżej, ponieważ polecenie curl domyślnie je zawiera.

Krok 6: Obsłuż zwróconą odpowiedź:

{
"refundId": "RE6-9YD-ULU-MRL",
"status": "PENDING"
}

Odpowiedź zawiera ID zwrotu wygenerowanego przez Paynow i aktualny status zwrotu. Zwrócony refundId powinien zostać zapisany przez Merchanta w celu późniejszego wykorzystania.

Krok 7: Zapytaj o status zwrotu. Sprawdź opis endpointu zapytania o status.

  curl --location --request GET 'https://api.sandbox.paynow.pl/v3/refunds/RE6-9YD-ULU-MRL/status' \
--header 'Api-Key: 97a55694-5478-43b5-b406-fb49ebfdd2b5' \
--header 'Idempotency-Key: 6228e8f1-4fd9-40bc-9660-37b03c968590' \
--header 'Signature: Aqy2xIQAZghJX4jdzeMZa7I/3WcI2saIAt0qzLoZiMU='

Zamiast odpytywać o status, możesz przekazać notificationUrl w Kroku 1 i zaczekać na powiadomienie.

Aby zobaczyć więcej szczegółów na temat statusów, zapoznaj się z Mapą statusów zwrotu

Anulowanie zwrotu oczekującego​

Jeśli włączyłeś mechanizm Zwrotów oczekujących, każdy nowy zwrot z salda zostanie wykonany z pewnym opóźnieniem. Kiedy zwrot ma status NEW (oczekujący), możesz go anulować za pomocą żądania API. To samo żądanie anuluje zwrot przelewem, który nadal oczekuje na przelew bankowy. Poniżej możesz zobaczyć, jak to zrobić.

Na potrzeby tego przewodnika przyjmiemy założenie, że dane autoryzacyjne to:

  • Api-Key = 97a55694-5478-43b5-b406-fb49ebfdd2b5
  • Refund Id = RE1-K7E-206-31J

Krok 1: Wygeneruj losowy ciąg o maksymalnej długości 45 znaków dla nagłówka Idempotency-Key.

Krok 2: Wykonaj poniższe żądanie do naszego API:

curl --location --request POST 'https://api.sandbox.paynow.pl/v3/refunds/RE6-9YD-ULU-MRL/cancel' \
-H 'Api-Key: 97a55694-5478-43b5-b406-fb49ebfdd2b5' \
-H 'Signature: e3JjMoexXydWjfBX8ArbExJu8YhTycwKEk0uWc9rXuM='

Należy pamiętać, że za pomocą tego żądania można anulować wyłącznie zwroty w statusie NEW: zwroty oczekujące z salda oraz zwroty przelewem, dla których przelew nie został jeszcze zaksięgowany.

Zwrot przelewem​

Zwrot przelewem pozwala zwrócić płatność nawet wtedy, gdy na Twoim saldzie nie ma wystarczających środków. Zamiast pobierać środki z salda, Paynow zwraca dane do przelewu bankowego, który należy wykonać w celu pokrycia zwrotu. Gdy przelew zostanie zaksięgowany na rachunku zwrotów Paynow, zwrot zostaje przetworzony, a środki są przekazywane kupującemu.

Jak to działa​

  1. (Opcjonalnie) Zlecasz standardowy zwrot i otrzymujesz błąd INSUFFICIENT_BALANCE_FUNDS, co oznacza brak wystarczających środków na saldzie.
  2. Zlecasz zwrot przelewem i określasz, jak długo Paynow ma czekać na przelew (validityTime, od 3 do 10 dni).
  3. Paynow tworzy zwrot w statusie NEW i zwraca dane do przelewu (bankTransferData): numer rachunku, kwotę, walutę, tytuł oraz dane odbiorcy. Zwrot nie jest jeszcze przetwarzany.
  4. Wykonujesz przelew bankowy.
  5. Gdy przelew zostanie zaksięgowany na rachunku zwrotów Paynow, zwrot jest przetwarzany, a środki trafiają do kupującego.
  6. Jeśli przelew nie zostanie zaksięgowany w czasie validityTime, zwrot zostaje anulowany (CANCELLED).
  7. Jeśli podałeś notificationUrl, Paynow wyśle powiadomienie, gdy zwrot zostanie zakończony, nie powiedzie się lub zostanie anulowany.
Ważne

Przelew musi dokładnie odpowiadać zwróconym danym bankTransferData – ta sama kwota i waluta, na podany numer rachunku oraz z podanym tytułem (title). W przeciwnym razie Paynow nie będzie w stanie powiązać przelewu ze zwrotem i zwrot nie zostanie przetworzony.

Utwórz zwrot przelewem​

Wymagane nagłówki są takie same jak dla standardowego zwrotu: Api-Key, Signature, Idempotency-Key, Content-Type, Host oraz Accept.

Krok 1: Przygotuj wiadomość z żądaniem zwrotu:

{
"amount": 10000,
"reason": "RMA",
"validityTime": 432000,
"notificationUrl": "https://shop.example.com/paynow/refund-notifications"
}
  • amount (wymagane) – kwota zwrotu w najmniejszej jednostce waluty (np. grosz dla PLN).
  • validityTime (wymagane) – czas w sekundach, przez jaki Paynow oczekuje na przelew bankowy (od 259200 do 864000, czyli od 3 do 10 dni).
  • reason (opcjonalne) – powód zwrotu (RMA, REFUND_BEFORE_14, REFUND_AFTER_14, OTHER).
  • notificationUrl (opcjonalne) – adres URL dla powiadomień o statusie zwrotu.

Krok 2: Dołącz nagłówek Api-Key, oblicz podpis i dołącz go jako nagłówek Signature, wygeneruj Idempotency-Key.

Krok 3: Wykonaj żądanie POST z przygotowaną wiadomością na endpoint zwrotu przelewem:

curl --location 'https://api.sandbox.paynow.pl/v3/payments/NOM3-VWX-YS7-J43/refunds/accounts' \
--header 'Api-Key: 97a55694-5478-43b5-b406-fb49ebfdd2b5' \
--header 'Signature: {calculated-signature}' \
--header 'Idempotency-Key: {idempotency-key}' \
--header 'Content-Type: application/json' \
--data '{
"amount": 10000,
"reason": "RMA",
"validityTime": 432000,
"notificationUrl": "https://shop.example.com/paynow/refund-notifications"
}'

Krok 4: Obsłuż zwróconą odpowiedź:

{
"refundId": "RE6-9YD-ULU-MRL",
"status": "NEW",
"bankTransferData": {
"accountNumber": "{refund-account-number}",
"amount": 10000,
"currency": "PLN",
"title": "{transfer-title}",
"recipientName": "{recipient-name}",
"recipientAddress": "{recipient-address}"
}
}

Krok 5: Wykonaj przelew bankowy zgodnie z bankTransferData – dokładna kwota i waluta, na podany numer rachunku oraz z podanym tytułem (title).

Krok 6: Zaczekaj na powiadomienie lub odpytaj o status zwrotu zgodnie z opisem w sekcji Utwórz zwrot, Krok 7. Do momentu zaksięgowania przelewu zwrot pozostaje w statusie NEW.

Aby anulować zwrot przelewem przed zaksięgowaniem przelewu, użyj żądania anulowania.

Powiadomienia o statusie zwrotu​

Paynow może powiadomić Cię, gdy zwrot osiągnie status końcowy, w taki sam sposób jak w przypadku płatności. Powiadomienia działają dla wszystkich typów zwrotów. Są szczególnie przydatne dla zwrotów przelewem oraz zwrotów oczekujących, które mogą zostać zrealizowane nawet kilka dni po ich zleceniu – zamiast wielokrotnie odpytywać o status zwrotu, możesz polegać na powiadomieniu.

Aby otrzymywać powiadomienia, przekaż opcjonalne pole notificationUrl podczas zlecania zwrotu – zarówno standardowego zwrotu (w tym zwrotu oczekującego), jak i zwrotu przelewem. Adres ustawiany jest dla każdego zwrotu osobno. Jeśli go nie podasz, powiadomienia dla tego zwrotu nie będą wysyłane.

Powiadomienia są wysyłane wyłącznie wtedy, gdy zwrot zmieni status na jeden ze statusów końcowych:

CodeDescription
SUCCESSFULZwrot został pomyślnie przetworzony, a środki zostały przekazane kupującemu.
FAILEDWystąpił problem podczas przetwarzania zwrotu.
CANCELLEDZwrot został anulowany przez API lub z powodu upływu czasu validityTime.

Paynow wysyła żądanie POST z nagłówkami Content-Type: application/json oraz Signature na podany adres notificationUrl:

{
"refundId": "RE6-9YD-ULU-MRL",
"status": "SUCCESSFUL"
}

Gdy status przyjmuje wartość FAILED, powiadomienie zawiera dodatkowo pole failureReason (CARD_BALANCE_ERROR, BUYER_ACCOUNT_CLOSED lub OTHER):

{
"refundId": "RE6-9YD-ULU-MRL",
"status": "FAILED",
"failureReason": "OTHER"
}
  • Zweryfikuj nagłówek Signature w taki sam sposób jak dla powiadomień o płatnościach – zobacz Podpis dla powiadomień. Jeśli podpis się nie zgadza, nie przetwarzaj wiadomości.
  • Odpowiedz statusem 200 OK lub 202 Accepted z pustym body. Każda inna odpowiedź jest traktowana jako błąd dostarczenia.
  • Nieudane próby dostarczenia są ponawiane zgodnie z tym samym harmonogramem co dla płatności. Jeśli wszystkie próby zakończą się niepowodzeniem, odpytaj o status zwrotu.
  • To samo powiadomienie może zostać dostarczone więcej niż raz – upewnij się, że jego obsługa po Twojej stronie jest idempotentna.