CodeGym /Kursy /ChatGPT Apps /ACP / Instant Checkout: standard i jego implementacja w C...

ACP / Instant Checkout: standard i jego implementacja w ChatGPT

ChatGPT Apps
Poziom 14 , Lekcja 3
Dostępny

1. Po co jest ACP i dlaczego to nie jest „jeszcze jedno REST API”

Jeśli patrzeć cynicznie, ACP wygląda jak zestaw zwykłych endpointów HTTP i struktur JSON: jakiś /checkout_sessions, jakieś webhooks, jakieś tokeny. Łatwo pomyśleć: „Okej, to kolejny niestandardowy API od kolejnej platformy”. Ale idea ACP jest głębsza.

ACP jest pomyślany jako otwarty protokół interakcji między trzema uczestnikami: platformą AI (na przykład ChatGPT), waszym backendem commerce i dostawcą płatności. Jego cel — standaryzować, jak opisywać produkty i ceny, jak AI ogłasza zamiar zakupu przez użytkownika, jak tworzy się sesja checkout, jak wykonywana jest płatność i jak wszyscy uczestnicy poznają końcowy status.

Kluczowa myśl: ten sam backend merchanta, implementujący ACP, potencjalnie może działać nie tylko z ChatGPT, ale i z innymi platformami LLM, które poprą ten standard. Czyli nie piszecie „specjalnego API dla ChatGPT”, lecz implementujecie protokół integracji commerce następnej generacji.

Instant Checkout w ChatGPT — to pierwsza duża implementacja standardu ACP. ChatGPT przestrzega tego protokołu, wywołując wasze endpointy ACP i pokazując użytkownikowi ładny UI, ale same zasady gry opisane są w specyfikacjach ACP, a nie schowane „magią GPT” gdzieś w czarnej skrzynce.

2. Trzy filary ACP: Product Feed, Agentic Checkout, Delegated Payment

ACP ma trzy główne specyfikacje, które będziemy stale przywoływać:

Specyfikacja Za co odpowiada Gdzie to widoczne w GiftGenius
Product Feed Spec Format i pola feedu produktowego (SKU, ceny, dostępność, linki, flagi). JSON/CSV feed z prezentami, który indeksuje OpenAI.
Agentic Checkout Kontrakt REST dla checkout_session: tworzenie, aktualizacja, finalizacja. Nasz backend ACP: endpointy /checkout_sessions i webhooks.
Delegated Payment Jak dane płatnicze są przekazywane merchantowi w postaci delegowanego tokena. Praca ze Stripe Shared Payment Token przy finalizacji płatności.

Product Feed omówiliśmy w poprzednich wykładach. Teraz interesują nas dwa ostatnie bloki: Agentic Checkout i Delegated Payment.

Ważne rozróżniać trzy poziomy:

  1. Specyfikacja (SPEC). Oficjalne dokumenty opisują, jakie pola i endpointy muszą istnieć, jakie statusy są legalne i jakie gwarancje zobowiązujecie się zapewnić.
  2. Wzorzec architektoniczny (ARCH). Na przykład decyzja, aby przechowywać SKU i zamówienia w osobnych tabelach, dodać usługę‑wrapper wokół ACP albo użyć kolejki dla webhooków. To dobre praktyki, ale nie część standardu.
  3. Konkretny przykład implementacji (przykład GiftGenius). To nasz projekt edukacyjny: struktura naszych tabel, dokładne nazwy typów w TypeScript, jak logujemy zamówienia itd. Wszystko to jest przykładem, a nie dokumentem normatywnym.

Będziemy stale podkreślać, gdzie kończy się SPEC, a zaczyna wasza architektura — aby nie wyszło „zobaczyłem w wykładzie pole persona_tags i uznałem, że to część oficjalnej specyfikacji”.

3. Checkout session od środka: struktura i statusy

Centralnym obiektem Agentic Checkout Spec jest checkout_session w waszym backendzie. Logicznie to stan zakupu: jakie produkty, na jaką kwotę, z jakimi opcjami dostawy i w jakim statusie znajduje się próba płatności.

Specyfikacja opisuje obligatoryjne pola checkout_session mniej więcej tak (sformułowania uproszczone i częściowo skrócone w stosunku do oryginału):

  • id — łańcuchowy identyfikator sesji, który generujecie i zwracacie. ChatGPT będzie go używać we wszystkich kolejnych wywołaniach.
  • buyer — informacje o kupującym: imię, email, telefon, czasem adres. W realnej specyfikacji ten obiekt jest zestrukturyzowany, aby PSP i wasze systemy mogły go niezawodnie wykorzystać.
  • status — łańcuchowy enum odzwierciedlający bieżący stan zakupu. Podstawowe statusy:
    • not_ready_for_payment — jeszcze nie można płacić (na przykład nie wybrano wariantu dostawy albo nie przeliczono podatków).
    • ready_for_payment — wszystko gotowe, można żądać tokenu płatniczego i obciążać środki.
    • completed — płatność zakończyła się powodzeniem, zamówienie utworzone.
    • canceled — zakup anulowany (z inicjatywy użytkownika lub z powodu błędu).
  • currency — kod waluty w formacie ISO 4217 małymi literami ("usd", "eur" itd.).
  • line_items — lista pozycji w koszyku, każda ze swoim SKU, ilością i wyliczonym kosztem.
  • fulfillment_address — adres dostawy (jeśli dotyczy).
  • fulfillment_options i fulfillment_option_id — możliwe warianty dostawy (lub realizacji) i aktualny wybrany wariant.
  • totals — sumy zagregowane: koszt towarów, podatki, dostawa, kwota końcowa.
  • order — obiekt opisujący zamówienie, które zostanie utworzone po pomyślnym zakończeniu sesji.
  • messages — lista komunikatów użytkownika, które ChatGPT może pokazać kupującemu: na przykład ostrzeżenia lub błędy.
  • links — lista linków, na przykład do polityki zwrotów, Privacy Policy i Terms of Service.

Nie musimy w demie implementować wszystkich pól, ale ważne jest zrozumienie idei: checkout_session to „historia i bieżący stan jednej próby zakupu”, i ChatGPT oczekuje, że zobaczy w niej wszystko, co potrzebne dla poprawnego UX.

Żeby było prościej, wprowadźmy w naszym kodzie edukacyjnym uproszczony typ:

// Uproszczony model checkout_session dla GiftGenius (niepełna SPEC)
type GGCheckoutStatus = 'not_ready_for_payment' | 'ready_for_payment' | 'completed' | 'canceled';

type GGLineItem = { skuId: string; quantity: number; total: number };

type GGCheckoutSession = {
  id: string;
  status: GGCheckoutStatus;
  currency: 'usd';
  lineItems: GGLineItem[];
  grandTotal: number;
};

Ten model jest z założenia prostszy od oficjalnego, ale świetnie nadaje się do praktyki: uczyć się trzymać w głowie statusy i przejścia, nie tonąc w setce pól.

4. Cykl życia checkout_session

Specyfikacja Agentic Checkout opisuje kilka operacji na checkout_session. W uproszczonej formie cykl życia wygląda tak:

  1. Utworzenie sesji: POST /checkout_sessions.
  2. Aktualizacja sesji: POST /checkout_sessions/{id}.
  3. Zakończenie sesji (complete): POST /checkout_sessions/{id}/complete.
  4. (Czasem) Anulowanie: osobny endpoint cancel lub przejście w canceled poprzez aktualizację.

Patrząc od strony stanów, można narysować taki diagram:

stateDiagram-v2
    [*] --> not_ready_for_payment
    not_ready_for_payment --> ready_for_payment: obliczenie dostawy/podatków
wybór opcji ready_for_payment --> completed: udany POST /complete ready_for_payment --> canceled: anulowanie przez użytkownika lub błąd not_ready_for_payment --> canceled: błąd, niezgodne dane

Utworzenie checkout_session zwykle startuje ją w stanie not_ready_for_payment albo od razu ready_for_payment, jeśli wszystko, co potrzebne do płatności, jest już znane (na przykład towar cyfrowy bez dostawy i podatków). Aktualizacje służą do dodawania danych (adres, kody rabatowe, wariant dostawy) i przeliczenia sum. Zakończenie — to moment, gdy wchodzi do gry Delegated Payment i środki są faktycznie pobierane.

Ważne jest tu zrozumienie podziału ról:

  • ChatGPT inicjuje utworzenie, aktualizacje i zakończenie sesji, opierając się na dialogu z użytkownikiem.
  • Wasz backend (merchant) odpowiada za poprawną logikę biznesową: weryfikację SKU, dostępności, kalkulację cen i podatków, zmianę statusów, tworzenie zamówień.
  • PSP (Stripe i inni) realizuje faktyczną płatność i wydaje Shared Payment Token, którego merchant używa do obciążenia środków.

Nieco dalej nałożymy na ten diagram stanów konkretne żądania HTTP i króciutkie przykłady kodu.

5. Tworzenie checkout_session: czego dokładnie oczekuje od nas ChatGPT

Gdy ChatGPT (lub agent) uzna, że użytkownik rzeczywiście chce coś kupić, formuje line items na podstawie Product Feed: listę SKU, ilości, proponowaną walutę i ewentualne dodatkowe życzenia dot. dostawy. Następnie wywołuje wasz endpoint POST /checkout_sessions.

Po stronie merchanta w tym momencie trzeba:

  1. Zweryfikować dane wejściowe: upewnić się, że wszystkie SKU istnieją, są dostępne do sprzedaży, nie łamią polityk (na przykład brak alkoholu dla nieletniego).
  2. Policzyć ceny i podatki na podstawie własnych zasad.
  3. Przygotować warianty dostawy (fulfillment options), jeśli towar jest fizyczny.
  4. Zwrócić poprawną checkout_session ze statusem i sumami.

Najprostszy handler na Express dla GiftGenius może wyglądać tak:

// Pseudokod: tworzenie uproszczonej checkout_session
app.post('/checkout_sessions', async (req, res) => {
  const items = req.body.lineItems as GGLineItem[];  // skuId + quantity
  const pricedItems = await priceItems(items);       // liczymy total dla każdego SKU
  const grandTotal = sum(pricedItems.map(i => i.total));

  const session: GGCheckoutSession = {
    id: generateId(),
    status: 'ready_for_payment', // dla cyfrowych prezentów można od razu przygotować do płatności
    currency: 'usd',
    lineItems: pricedItems,
    grandTotal,
  };

  res.status(201).json(session);
});

Tu robimy kilka rzeczy:

  • Nie ufamy wejściowym cenom od klienta (ChatGPT) i przeliczamy je według własnych danych — to krytyczne dla bezpieczeństwa commerce.
  • Generujemy własne id sesji (na przykład prefiks gg_chk_...).
  • Zwracamy status ready_for_payment, jeśli nie mamy dodatkowych kroków (brak dostawy, automatyczne podatki, prosty model).

W realnym backendzie zgodnym z ACP dodatkowo zwrócicie messages, links i złożony obiekt totals, a także wypełnicie order (choćby w wersji roboczej), jak to opisano w specyfikacji.

6. Aktualizacja checkout_session i idempotencja

Po utworzeniu sesji ChatGPT może poprosić użytkownika o dodatkowe szczegóły: adres dostawy, zastosowanie kuponu, zmianę wariantu realizacji. Gdy te dane się pojawią, platforma wywołuje POST /checkout_sessions/{id}, abyście zaktualizowali wyliczenia.

Z punktu widzenia kodu jest to bardzo podobne do tworzenia, ale zamiast generować nową sesję wy:

  • odnajdujecie istniejącą po id;
  • stosujecie zmiany (na przykład zmieniacie fulfillment_option_id albo dodajecie zniżkę);
  • przeliczacie sumy;
  • zwracacie zaktualizowaną checkout_session.

Ważne, że specyfikacja dopuszcza powtórne wywołania (z powodu awarii sieci lub retry po stronie ChatGPT). Dlatego, jak i w wcześniejszych modułach, gdzie mówiliśmy o idempotencji narzędzi i webhooków, tutaj zaleca się użycie Idempotency-Key w nagłówkach żądania i ostrożną obsługę powtórek.

Przykładowy handler aktualizacji mógłby wyglądać tak:

app.post('/checkout_sessions/:id', async (req, res) => {
  const id = req.params.id;
  const key = req.header('Idempotency-Key'); // ten sam key => jeden efekt
  const existing = await loadSessionWithIdempotency(id, key, req.body);

  // applyUpdates może w środku przeliczyć ceny, dostawę itd.
  const updated = await applyUpdates(existing, req.body);
  await saveSession(updated, key);

  res.json(updated);
});

Nie trzymamy się tu sztywno konkretnej struktury SPEC, a pokazujemy ideę: na wejściu — zmiany i klucz idempotentny, na wyjściu — spójny stan checkout_session. Jeśli przyjdzie identyczne żądanie z tym samym kluczem, powinniście zwrócić ten sam wynik, nie tworząc zbędnych zamówień ani duplikatów w logach.

7. Zakończenie checkout_session i Delegated Payment: jak działa Shared Payment Token

Najciekawszy i najbardziej nerwowy moment — zakończenie checkout_session, kiedy środki są faktycznie pobierane. Tu wchodzi druga specyfikacja: Delegated Payment.

Idea Delegated Payment

Użytkownik wprowadza lub wybiera dane płatnicze w interfejsie ChatGPT (karta, portfel, zapisany sposób płatności). Platforma nie wysyła tych danych bezpośrednio do was — zamiast tego prosi PSP (na przykład Stripe) o specjalny token, Shared Payment Token (SPT), który:

  • jest jednoznacznie powiązany z merchantem i konkretną sesją;
  • jest ograniczony kwotowo i czasowo;
  • nie ujawnia wam prawdziwego numeru karty.

W rezultacie wygląda to tak:

Aktor Widzi dane karty płatniczej Widzi Shared Payment Token Widzi szczegóły zamówienia (SKU, kwoty)
Użytkownik Tak (wprowadza je w UI) Nie (niepotrzebne) Częściowo (co kupuje i za ile)
ChatGPT/OpenAI Tak (w procesie płatności) Tak Tak
PSP (Stripe) Tak Tak W ramach płatności
Merchant Nie Tak Tak

Taki projekt pozwala merchantowi uniknąć przechowywania danych płatniczych i skupić się na logice biznesowej zamówienia, zostawiając kwestie compliance PSP i platformie.

Insight

Sens Shared Payment Token polega na tym, by ukryć przed waszym backendem dane karty, ale żeby to wy przeprowadziliście płatność. Można jednak spojrzeć na to jeszcze inaczej.

Pewnie kojarzycie sytuację, gdy sklep lub hotel najpierw blokuje środki (hold) na karcie, a potem po czasie je pobiera. I tak właśnie: traktujcie Shared Payment Token jak token blokady (hold‑token). ChatGPT zablokował środki na koncie użytkownika, ale ich nie pobrał. Przekazał wam ten token blokady i teraz możecie przekazać go Stripe i obciążyć środki.

Tu są dwa ważne niuanse:

  • kwoty blokady i obciążenia nie powinny znacząco się różnić, a najlepiej żeby się pokrywały;
  • możecie sprzedać przez ChatGPT pierwszy miesiąc subskrypcji za $1, a potem pobierać co miesiąc $49.99

Żądanie POST /checkout_sessions/{id}/complete

Gdy użytkownik naciska przycisk potwierdzenia płatności w Instant Checkout, ChatGPT:

  1. Żąda SPT u PSP (na przykład przez Stripe ACP API).
  2. Wysyła ten token do waszego backendu przez POST /checkout_sessions/{id}/complete wraz z danymi kupującego.

Specyfikacja opisuje treść żądania mniej więcej tak (poniżej zaadaptowany i skrócony przykład z oficjalnej dokumentacji):

POST /checkout_sessions/checkout_session_123/complete

{
  "buyer": {
    "first_name": "John",
    "last_name": "Smith",
    "email": "johnsmith@mail.com"
  },
  "payment_data": {
    "token": "spt_123",
    "provider": "stripe"
  }
}

Wasz backend powinien na to:

  1. Odnaleźć checkout_session o id checkout_session_123.
  2. Sprawdzić, czy status pozwala na zakończenie (zwykle ready_for_payment).
  3. Utworzyć płatność u PSP, używając tokenu spt_123 (sposób zależy od PSP, w przypadku Stripe — określony endpoint i typ metody płatności).
  4. Poczekać na potwierdzenie operacji płatniczej.
  5. Zaktualizować checkout_session do completed, utworzyć i zapisać zamówienie, wypełnić pole order w strukturze sesji.
  6. Zwrócić aktualny checkout_session w odpowiedzi.

W bardzo uproszczonym TypeScript‑pseudokodzie mogłoby to wyglądać tak:

app.post('/checkout_sessions/:id/complete', async (req, res) => {
  const { id } = req.params;
  const { buyer, payment_data } = req.body;
  const session = await loadSession(id);

  await chargeWithSharedToken(payment_data.token, session.grandTotal);
  const completed = await markSessionCompleted(session, buyer);

  res.json(completed);
});

W realnym świecie między tymi liniami kryją się obsługa błędów, ponowne próby, logowanie i integracja z waszym modelem zamówień.

Jeśli coś pójdzie nie tak (na przykład płatność zostanie odrzucona), powinniście zwrócić checkout_session ze statusem not_ready_for_payment lub canceled i wypełnić messages tak, aby ChatGPT mógł poprawnie wyjaśnić użytkownikowi, co się stało.

8. Instant Checkout w ChatGPT: jak wszystko składa się w jeden przepływ

Teraz złóżmy te kawałki w spójny scenariusz „od zamiaru do płatności” w ChatGPT. Wykład można traktować jako „dekodowanie” tego, co kryje się za jednym przyciskiem „Kup” w widżecie.

Uproszczony scenariusz:

  1. Użytkownik pisze: „Dobierz cyfrowy prezent dla znajomego do $50 i od razu sfinalizuj zakup”.
  2. Agent (lub sam ChatGPT App) używa Product Feed, aby znaleźć odpowiednie SKU w ramach budżetu.
  3. ChatGPT pokazuje w czacie kilka kart prezentów (przez wasz widżet GiftGenius) i proponuje wybrać jeden.
  4. Po wyborze ChatGPT formuje line items i wywołuje POST /checkout_sessions na waszym backendzie ACP, otrzymując checkout_session z sumami i statusem.
  5. W UI Instant Checkout użytkownik widzi kwotę końcową, nazwę towaru, politykę zwrotów i przycisk potwierdzenia.
  6. Przy potwierdzeniu ChatGPT pobiera Shared Payment Token u PSP i wywołuje POST /checkout_sessions/{id}/complete, jak omawialiśmy wyżej.
  7. Wasz backend przeprowadza płatność, tworzy zamówienie, zwraca checkout_session ze statusem completed.
  8. ChatGPT pokazuje użytkownikowi potwierdzenie, a wasz backend (przez webhooks zgodnie z Agentic Checkout Spec) może wysłać zdarzenie z powrotem do OpenAI, aby platforma wiedziała o losie zamówienia.

W formie diagramu sekwencji wygląda to tak:

sequenceDiagram
    actor U as Użytkownik
    participant GPT as ChatGPT
    participant GG as Backend ACP GiftGenius
    participant PSP as Stripe (PSP)

    U->>GPT: Chcę prezent do $50 i kupić go od razu tutaj
    GPT->>GG: POST /checkout_sessions (line_items)
    GG-->>GPT: checkout_session (ready_for_payment)
    GPT->>U: Pokazuje Instant Checkout (produkt, cena, ToS)
    U->>GPT: Naciska „Potwierdź płatność”
    GPT->>PSP: Żądanie SPT dla kwoty i merchanta
    PSP-->>GPT: Shared Payment Token (spt_xxx)
    GPT->>GG: POST /checkout_sessions/{id}/complete (token + buyer)
    GG->>PSP: Płatność z SPT
    PSP-->>GG: Płatność zakończona sukcesem
    GG-->>GPT: checkout_session (completed + order)
    GPT-->>U: Pokazuje potwierdzenie zakupu

W tym scenariuszu nigdzie nie pojawia się „dowolne” wywołanie waszej bazy czy dziwne wewnętrzne endpointy. Wszystko mieści się w ściśle opisanym kontrakcie ACP, gdzie każdy uczestnik zna swoją rolę.

9. Mini‑praktyka: uproszczony backend ACP dla GiftGenius

Aby ten wykład nie pozostał czystą teorią, warto mentalnie „przewinąć” implementację warstwy ACP dla naszego projektu edukacyjnego.

Wyobraźcie sobie, że GiftGenius już ma:

  • Bazę SKU i cen, na podstawie której tworzymy Product Feed (modelowaliśmy to w poprzednich wykładach).
  • Prosty model zamówień: tabela orders z polami id, userId, skuId, amount, currency, status, createdAt.
  • Interfejs ChatGPT App i warstwę MCP, która potrafi rekomendować prezenty (budowaliśmy to w poprzednich modułach kursu).

Teraz wasze zadanie — dodać na to jeszcze jeden mały serwis gg-acp:

  • Endpoint POST /checkout_sessions:
    • Przyjmuje listę SKU i ilości.
    • Przelicza sumy na podstawie waszej bazy.
    • Tworzy robocze zamówienie (na przykład ze statusem pending) i checkout_session ze statusem ready_for_payment.
    • Zwraca checkout_session.
  • Endpoint POST /checkout_sessions/{id}:
    • Odnajduje sesję i zamówienie.
    • Stosuje zmiany (na przykład wsparcie kodu promocyjnego, który zmniejsza kwotę końcową).
    • Zwraca zaktualizowaną checkout_session.
  • Endpoint POST /checkout_sessions/{id}/complete:
    • Otrzymuje SPT, kwotę i dane kupującego.
    • W wersji demo może po prostu oznaczać zamówienie jako „opłacone” bez rzeczywistego wywołania integracyjnego do PSP (albo możecie zasymulować Stripe).
    • Aktualizuje checkout_session do statusu completed i podłącza do niej order_id.

Cały ten serwis można zrealizować w jednej małej aplikacji Node/Express lub jako endpointy w Next.js App Router. Najważniejsze — trzymać się kontraktu co do formatu i statusów, nawet jeśli płatność jest emulowana.

Przykładowy model zamówienia w TypeScript może wyglądać tak:

// Uproszczony model zamówienia GiftGenius
type GGOrderStatus = 'pending' | 'paid' | 'canceled';

type GGOrder = {
  id: string;
  userId: string;
  skuId: string;
  amount: number;
  currency: 'usd';
  status: GGOrderStatus;
};

W produkcji na to nałożą się powiązania z waszym Auth/Identity (aby wiedzieć, kim jest użytkownik czatu), webhooks do OpenAI i bardziej złożone scenariusze zwrotów. Ale jako krok edukacyjny w ramach tego wykładu wystarczy nauczyć się pewnie przechodzić pętlę: utworzyć sesję → zaktualizować → zakończyć, nie gubiąc przy tym pieniędzy i zdrowego rozsądku.

10. Typowe błędy przy projektowaniu ACP / Instant Checkout

Błąd nr 1: mieszanie ról („ChatGPT to mój sklep”).
Czasem deweloperzy myślowo mianują ChatGPT „centralnym systemem ewidencji” i próbują trzymać stan biznesowy zamówienia po stronie platformy: „skoro jest checkout_session, to historię zamówień będę czytać z OpenAI”. To ślepa uliczka. checkout_session to obiekt protokołu, a nie źródło prawdy o zamówieniach. Źródłem prawdy jest wasz backend commerce: to tam powinny żyć zamówienia, statusy, zwroty i raporty. ChatGPT w tym schemacie jest jedynie zaufanym „frontendem w czacie”.

Błąd nr 2: ufanie wejściowym cenom od ChatGPT.
Łatwo pomyśleć: „agent już dobrał SKU i nawet policzył kwotę, przyjmijmy tę kwotę i pobierzmy środki”. Tak nie wolno. Wejście z ChatGPT (line items, proponowane ceny) trzeba traktować jako propozycję, a nie rozkaz. Wasz backend ma obowiązek samodzielnie sprawdzić SKU, ceny, dostępność, stosowalność rabatów itd., porównując to z Product Feed i własną bazą. Inaczej pojawi się wesoła klasa bugów „użytkownik kupił towar za $0.01, bo model postanowił zaokrąglić”.

Błąd nr 3: ignorowanie statusów i maszyny stanów.
We wczesnych prototypach często robi się „dziurawą” implementację: status sesji zawsze completed, albo po prostu ok, a wszelkie rozbieżności z faktycznym stanem płatności chowa się w środku. W efekcie ChatGPT nie może poprawnie pokazać użytkownikowi, co się dzieje: płatność jest w toku, już się zakończyła czy została anulowana. Znacznie lepiej uczciwie zaimplementować maszynę stanów not_ready_for_paymentready_for_paymentcompleted/canceled i zwracać realny status z backendu, zamiast wymyślać własne ad‑hoc pola.

Błąd nr 4: używanie Shared Payment Token jako „karty wielokrotnego użytku”.
SPT z założenia jest tokenem jednorazowym lub ściśle ograniczonym: jest powiązany z konkretną operacją, kwotą i merchantem. Próby cache’owania go „na wszelki wypadek” lub użycia ponownie do innego zakupu — to zły pomysł. W najlepszym razie PSP odrzuci drugą próbę; w najgorszym — pogubicie ewidencję płatności i zamówień. Dla każdego checkout_session.complete powinien być świeży token, a jeśli płatność się nie udała — trzeba żądać nowego.

Błąd nr 5: brak idempotencji w /checkout_sessions i webhookach.
W realnej sieci żądania mogą się dublować: ChatGPT może powtórzyć POST /checkout_sessions po timeoutcie, PSP może ponownie wysłać webhook po czasowym błędzie. Jeśli wasza implementacja za każdym razem tworzy nowe zamówienie i nowy wpis w bazie, szybko dostaniecie chaos: podwójne obciążenia, duplikaty zamówień i dziwne rozbieżności między systemami. Użycie Idempotency-Key, kontrola powtórzeń i przechowywanie wyników poprzednich wywołań — to nie „opcjonalna optymalizacja”, lecz niezbędny element niezawodnej integracji ACP.

Błąd nr 6: zapomnienie o powiązaniu z Product Feed.
Czasem warstwa ACP jest projektowana „w próżni”: SKU i ceny bierze się z jakichś wewnętrznych tabel, które nie pokrywają się z tym, co trafia do Product Feed. W efekcie ChatGPT pokazuje użytkownikowi jedno (według feedu), a w checkout przez ACP przechodzi coś zupełnie innego. Aby uniknąć takich niespodzianek, ważne jest, by wasz model SKU i cen był spójny: feed, backend ACP i wewnętrzna baza muszą patrzeć na to samo źródło prawdy, nawet jeśli nad nim są różne projekcje i cache’e.

Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION