← Wszystkie poradniki

PORADNIK 4 / 12

Utwórz stronę płatności. Zweryfikuj płatność.

Twórz faktury z backendu i przetwarzaj zweryfikowane powiadomienia o płatnościach.

Co uzyskasz

Proces płatności po stronie serwera z ponawianiem i ochroną przed duplikatami.

1. Przygotuj identyfikatory i dostęp

Zacznij od włączonego sklepu i przetestowanych metod płatności. W Ustawienia → Dostęp APIutwórz dane dostępu do odczytu/zapisu ograniczone do potrzebnego projektu. Trzymaj token na backendzie, nigdy w kodzie przeglądarki ani publicznym repozytorium.

Skopiuj Identyfikator API projektu i Identyfikator API sklepu z pola sklepu Podstawowe → Identyfikatory API . To UUID, nie czytelny identyfikator projektu ani numer zamówienia. Używaj własnej nazwy hosta API.

W Sklep → IPN, utwórz sekret podpisujący przed podaniem ipn_url. Twój odbiornik HTTPS musi być osiągalny z VPS sprzedawcy.

2. Utwórz fakturę

Zastąp symbole zastępcze i wyślij to żądanie z backendu. Kwoty są ciągami dziesiętnymi, nie obliczeniami zmiennoprzecinkowymi.

curl --fail-with-body --request POST \
  'https://api.example.com/v1/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/invoices' \
  --header 'Authorization: Bearer YOUR_MERCHANT_API_TOKEN' \
  --header 'Content-Type: application/json' \
  --header 'Idempotency-Key: order-1042-attempt-1' \
  --data '{
  "amount": "10.00",
  "currency": "EUR",
  "order_id": "order-1042",
  "description": "Example order",
  "ipn_url": "https://shop.example.com/payments/wholly-ipn",
  "metadata": {
    "cart_id": "cart-1042"
  }
}'

Zapisz data.invoice_id przy zamówieniu, a następnie przekieruj klienta do links.checkout. Użyj unikalnego klucza idempotencji dla nowej próby płatności. Przy przekroczeniu czasu ponów z tymi samymi danymi dostępu, kluczem i dokładnie tymi samymi bajtami treści.

Pominięcie payment_methods używa akceptowanych metod sklepu. Możesz je zawęzić dla faktury za pomocą identyfikatorów blockchainów i symboli; nigdy nie włącza to nieakceptowanego aktywa. Wszystkie pola żądania i przykłady odpowiedzi →

3. Wybierz IPN, webhooki lub oba

IPN śledzi cykl życia faktury. Ustaw domyślny URL IPN sklepu lub zastąp go przez ipn_url dla faktury. Webhooki subskrybują endpoint na wybrane zdarzenia, na przykład invoice.settled.

Używają tego samego formatu podpisu, ale różnych sekretów: IPN używa sekretu IPN sklepu; każdy endpoint webhooka ma własny sekret. Żaden nie używa tokena bearer API do podpisywania.

Jeśli oba dostarczają powiadomienia do aplikacji, oczekuj nakładających się powiadomień. Nie uznawaj płatności zamówienia dwa razy.

4. Zweryfikuj i zapisz powiadomienie

  1. Odczytaj dokładną surową treść żądania przed parsowaniem JSON. Zweryfikuj Wholly-Signature właściwym sekretem oraz kontrolami znacznika czasu i ponownego odtworzenia. Oficjalne SDK udostępniają weryfikatory.
  2. Zweryfikuj tożsamość projektu, sklepu, faktury i zdarzenia w podpisanej treści. Niepodpisane nagłówki dostarczenia nie są źródłem uwierzytelnienia.
  3. Trwale zapisz zdarzenie z unikalnym event_id, a następnie szybko zwróć HTTP 2xx. Przetwarzaj zamówienia w procesie roboczym w tle.
  4. Pobierz aktualną fakturę ze skonfigurowanego hosta API, nie dowolnego hosta podanego w żądaniu. Porównaj zapisany projekt, sklep, kwotę, walutę i odwołanie do zamówienia.

PHP · Python · JavaScript / TypeScript · Specyfikacja podpisu i przykłady odbiornika

5. Zrealizuj raz, po rozliczeniu

W odbiorniku opartym na zdarzeniach obsłuż event_type = invoice.settled, a następnie zweryfikuj aktualne status = settled i swoją politykę wyjątków. Zrealizuj raz w ramach transakcji bazy danych/ograniczenia unikalności zamówienia.

Typ zdarzenia i status to różne rzeczy

Blockchain z szybką finalizacją może wysłać oba payment.received i invoice.settled z status = settled. W innym blockchainie payment.received może nadal wskazywać processing. Żaden z tych przebiegów nie jest błędem.

Usuwaj duplikaty zdarzeń według event_id, nie tylko numeru sekwencji: różne typy zdarzeń mogą współdzielić sekwencję. Procedury SDK oparte na stanie zamiast tego łączą rewizje faktury i sprawdzają stan niezależnie od typu zdarzenia. Nie łącz takiego scalania z filtrem typu zdarzenia. Oba podejścia nadal wymagają ochrony przed duplikatami na poziomie zamówienia.

Sprawdź requires_review i ręczne rozstrzygnięcia przed realizacją. amount_status = paid samo nie dowodzi potwierdzenia. Pola opłaconego aktywa najwyższego poziomu podsumowują rozliczenie; payment_info zawiera szczegółowe wpływy i dane wyceny. Wszystkie statusy, zdarzenia i reguły wyjątków →

6. Przetestuj ponawianie i odzyskiwanie

Przetestuj małą płatność, duplikat dostarczenia, wygasłą fakturę i tymczasowo niedostępny odbiornik. Powtórne odtworzenie zdarzenia nie może drugi raz uznać płatności zamówienia. Obsługuj zdarzenia poza kolejnością bez nadpisywania nowszego stanu.

Sprawdź Sklep → IPN / Webhooki → Historia → Szczegółylub sekcje dostarczenia w Szczegółach faktury. Ponowne wysłanie używa zapisanego zdarzenia, nie nowego rozliczenia.

Niskie saldo na przetwarzanie wstrzymuje IPN/webhooki, podczas gdy płatności są nadal przyjmowane. Uzgodnij zaległe zamówienia przez API i obsłuż zachowane dostarczenia po przywróceniu działania. Nigdy nie realizuj zamówienia na podstawie przekierowania przeglądarki lub zrzutu ekranu klienta.