Wdrożenie natywnego procesu płatności za pomocą interfejsu API REST

Ten przewodnik zawiera techniczną dokumentację interfejsu API i schematy ładunków dla wersji 2026-01-23 natywnego procesu płatności w protokole Universal Commerce Protocol (UCP).

Zanim zaczniesz tworzyć punkty końcowe, zapoznaj się z omówieniem natywnego procesu płatności, aby poznać ogólny przebieg procesu płatności, wymagania dotyczące uwierzytelniania i narzędzia dla deweloperów.

Tworzenie sesji płatności

Ten punkt końcowy umożliwia utworzenie sesji płatności zawierającej produkty, które użytkownik chce kupić.

  • Punkt końcowy: POST /checkout-sessions
  • Wywołanie: użytkownik klika „Kup teraz” przy produkcie lub „Płatność w Google” w koszyku.

Żądanie: Google wysyła elementy zamówienia i ograniczone informacje o adresie kupującego, które obejmują miasto, województwo i kod pocztowy.

// Request Example: Create checkout with multiple items.
{
  "line_items": [
    {
      "item": {
        // Must match ID in product feed
        "id": "product_12345"
      },
      "quantity": 1
    },
    {
      "item": {
        // Must match ID in product feed
        "id": "product_67890"
      },
      "quantity": 1
    }
  ],
  "context": {
    "language": "en"
  },
  "fulfillment": {
    "methods": [
      {
        "type": "shipping",
        "line_item_ids": [
          "line_1",
          "line_2"
        ],
        "destinations": [
          {
            "id": "addr_1",
            "address_locality": "Sunnyvale",
            "address_region": "CA",
            "postal_code": "94089",
            "address_country": "US"
          }
        ],
        "selected_destination_id": "addr_1"
      }
    ]
  }
}

Odpowiedź: zwracasz zainicjowaną sesję z sumami, podatkami (początkowo szacowanymi) i możliwościami płatności.

// Response Example: Initialize Session with multiple items.
{
  "ucp": {
    "version": "2026-01-23",
    "capabilities": {
      "dev.ucp.shopping.checkout": [ { "version": "2026-01-23" } ],
      "dev.ucp.shopping.fulfillment": [ { "version": "2026-01-23", "extends": "dev.ucp.shopping.checkout" } ]
    },
    "payment_handlers": {
      "com.google.pay": [
        {
          "id": "8c9202bd-63cc-4241-8d24-d57ce69ea31c",
          "version": "2026-01-23",
          "spec": "https://pay.google.com/gp/p/ucp/2026-01-23/",
          "schema": "https://pay.google.com/gp/p/ucp/2026-01-23/schemas/config.json",
          "config": {
            "api_version": 2,
            "api_version_minor": 0,
            "environment": "TEST",
            "merchant_info": {
              "merchant_name": "Example Merchant",
              "merchant_id": "KWMZPRLQFTYNXSDB",
              "merchant_origin": "checkout.merchant.com"
            },
            "allowed_payment_methods": [
              {
                "type": "CARD",
                "parameters": {
                  "allowed_auth_methods": [ "PAN_ONLY", "CRYPTOGRAM_3DS" ],
                  "allowed_card_networks": [
                    "AMEX",
                    "DISCOVER",
                    "JCB",
                    "MASTERCARD",
                    "VISA"
                  ],
                  "billing_address_required": true,
                  "billing_address_parameters": {
                    "format": "FULL",
                    "phone_number_required": true
                  }
                },
                "tokenization_specification": {
                  "type": "PAYMENT_GATEWAY",
                  "parameters": {
                    "gateway": "example",
                    "gatewayMerchantId": "exampleGatewayMerchantId"
                  }
                }
              }
            ]
          }
        }
      ]
    }
  },
  "id": "da2e25ec-eef8-41b7-a439-4e62dea41bdc",
  "status": "incomplete",
  "messages": [
    {
      "type": "error",
      "code": "missing_buyer_info",
      "path": "$.buyer",
      "content_type": "plain",
      "content": "Buyer information is required for checkout",
      "severity": "recoverable"
    },
    {
      "type": "error",
      "code": "missing_fulfillment_info",
      "path": "$.fulfillment.methods[0].destinations[0]",
      "content_type": "plain",
      "content": "Shipping address is incomplete",
      "severity": "recoverable"
    }
  ],
  "currency": "USD",
  "line_items": [
    {
      "id": "line_1",
      "item": {
        "id": "product_12345",
        "title": "Running Shoes",
        "price": 10000,
        "image_url": "https://merchant.example.com/images/product_12345.png"
      },
      "quantity": 1,
      "totals": [
        {
          "type": "subtotal",
          "amount": 10000
        },
        {
          "type": "total",
          "amount": 10000
        }
      ]
    },
    {
      "id": "line_2",
      "item": {
        "id": "product_67890",
        "title": "T-Shirt",
        "price": 2500,
        "image_url": "https://merchant.example.com/images/product_67890.png"
      },
      "quantity": 1,
      "totals": [
        {
          "type": "subtotal",
          "amount": 2500
        },
        {
          "type": "total",
          "amount": 2500
        }
      ]
    }
  ],
  "totals": [
    {
      "type": "subtotal",
      "display_text": "Subtotal", // Tax-inclusive markets: Set to "Subtotal (including taxes)".
      "amount": 12500 // Tax-inclusive markets: Amount must include tax.
    },
    {
      "type": "fulfillment",
      "display_text": "Ground Shipping", // Tax-inclusive markets: Provide display text for fulfillment totals.
      "amount": 500
    },
    {
      "type": "tax", // Tax-inclusive markets: Omit this entry.
      "display_text": "Estimated Tax",
      "amount": 100
    },
    {
      "type": "total",
      "amount": 13100
    }
  ],
  "fulfillment": {
    "methods": [
      {
        "id": "method_shipping",
        "type": "shipping",
        "line_item_ids": [
          "line_1",
          "line_2"
        ],
        "destinations": [
          {
            "id": "addr_1",
            "address_locality": "Sunnyvale",
            "address_region": "CA",
            "postal_code": "94089",
            "address_country": "US"
          }
        ],
        "selected_destination_id": "addr_1",
        "groups": [
          {
            "id": "group_1",
            "line_item_ids": [
              "line_1",
              "line_2"
            ],
            "options": [
              {
                "id": "ship_ground",
                "title": "Ground (3-5 days)",
                "description": "Estimated Delivery: Fri 5/8", // Maximum length: 200 characters.
                "totals": [ {"type": "total", "amount": 500} ]
              },
              {
                "id": "ship_express",
                "title": "Express (1-2 days)",
                "description": "Estimated Delivery: Wed 5/6", // Maximum length: 200 characters.
                "totals": [ {"type": "total", "amount": 1500} ]
              }
            ],
            "selected_option_id": "ship_ground"
          }
        ]
      }
    ]
  },
  "links": [
    {
      "type": "terms_of_service",
      "url": "https://m.com/terms",
      "title": "Terms of Service"
    },
    {
      "type": "privacy_policy",
      "url": "https://m.com/privacy",
      "title": "Privacy Policy"
    }
  ]
}

Ceny z podatkiem

W przypadku rynków, na których podatek jest uwzględniony w wyświetlanym podsumowaniu, a nie wyszczególniony osobno, podczas przesyłania danych sesji płatności musisz spełniać te wymagania:

  • Uwzględnij podatek w sumie częściowej: pole amount dla wpisu subtotal musi zawierać wszystkie obowiązujące podatki.
  • Pomiń osobne wpisy dotyczące podatku: nie uwzględniaj w tablicy totals osobnego obiektu z wartością type: "tax".
  • Podaj niestandardowy tekst wyświetlany: w obiekcie sumy częściowej musisz umieścić atrybut display_text, który wyraźnie wskazuje, że podatek jest wliczony w cenę, np. "Subtotal (including taxes)". Musisz też dodać atrybut display_text dla wpisów dotyczących realizacji zamówienia (np. "Shipping").

Przykład: tablica sum z podatkiem

Poniższy przykład pokazuje tablicę totals dla sprzedawcy na rynku, na którym podatek jest wliczony w cenę:

"totals": [
  {
    "type": "subtotal",
    "display_text": "Subtotal (including taxes)",
    "amount": 12500
  },
  {
    "type": "fulfillment",
    "display_text": "Shipping",
    "amount": 399
  },
  {
    "type": "total",
    "display_text": "Total",
    "amount": 12899
  }
]

Pobieranie sesji płatności

Ten punkt końcowy umożliwia pobranie sesji płatności.

  • Punkt końcowy: GET /checkout-sessions/{id}

Żądanie: Google wysyła identyfikator sesji płatności. Jeśli używasz identyfikatorów globalnych (np. gid://merchant.example.com/Checkout/session_abc123), pamiętaj, że identyfikator w ścieżce żądania będzie tylko ostatnim komponentem tego identyfikatora (np. session_abc123).

Odpowiedź: zwracasz pełny obiekt płatności. W przypadku sesji z wieloma produktami utworzonej w wersji 2026-01-23 lub nowszej tablica line_items będzie zawierać wiele wpisów dotyczących produktów.

Aktualizowanie sesji płatności

Ten punkt końcowy umożliwia aktualizowanie sesji płatności. Gdy adres dostawy zostanie zaktualizowany, musi ponownie obliczyć i zwrócić podatki oraz opcje dostawy.

  • Punkt końcowy: PUT /checkout-sessions/{id}

Zaktualizuj adres dostawy

  • Wywołanie: użytkownik wybiera lub zmienia adres dostawy.

Żądanie: Google aktualizuje adres realizacji, gdy użytkownik zmieni adres dostawy.

// Request Example: Update shipping address with multiple items.
{
  "line_items": [
    {
      // line_items id from Create Checkout response
      "id": "line_1",
      "item": {
        "id": "product_12345"
      },
      "quantity": 1
    },
    {
      // line_items id from Create Checkout response
      "id": "line_2",
      "item": {
        "id": "product_67890"
      },
      "quantity": 1
    }
  ],
  "fulfillment": {
    "methods": [
      {
        "id": "method_shipping",
        "type": "shipping",
        "line_item_ids": [
          "line_1",
          "line_2"
        ],
        "destinations": [
          {
            "id": "addr_1",
            "address_locality": "Mountain View",
            "address_region": "CA",
            "postal_code": "94043",
            "address_country": "US"
          }
        ],
        "selected_destination_id": "addr_1",
        "groups": [
          {
            "id": "group_1",
            "selected_option_id": "ship_ground"
          }
        ]
      }
    ]
  }
}

Odpowiedź: w razie potrzeby ponownie obliczasz podatki i opcje dostawy oraz zwracasz pełny obiekt płatności.

// Response Example: Updated session with new address for multiple items.
{
  "id": "da2e25ec-eef8-41b7-a439-4e62dea41bdc",
  "currency": "USD",
  "line_items": [
    {
      "id": "line_1",
      "item": {
        "id": "product_12345",
        "title": "Running Shoes",
        "price": 10000,
        "image_url": "https://merchant.example.com/images/product_12345.png"
      },
      "quantity": 1,
      "totals": [
        { "type": "subtotal", "amount": 10000 },
        { "type": "total", "amount": 10000 }
      ]
    },
    {
      "id": "line_2",
      "item": {
        "id": "product_67890",
        "title": "T-Shirt",
        "price": 2500,
        "image_url": "https://merchant.example.com/images/product_67890.png"
      },
      "quantity": 1,
      "totals": [
        { "type": "subtotal", "amount": 2500 },
        { "type": "total", "amount": 2500 }
      ]
    }
  ],
  "totals": [
     { "type": "subtotal", "amount": 12500 },
     // Shipping cost might change based on new address
     { "type": "fulfillment", "display_text": "Ground Shipping", "amount": 600 },
     // Tax will likely change based on new address
     { "type": "tax", "amount": 1120 },
     { "type": "total", "amount": 14220 }
  ],
  "fulfillment": {
    "methods": [
      {
        "id": "method_shipping",
        "type": "shipping",
        "line_item_ids": ["line_1", "line_2"],
        "selected_destination_id": "addr_1",
        "destinations": [
          {
            "id": "addr_1",
            "address_locality": "Mountain View",
            "address_region": "CA",
            "postal_code": "94043",
            "address_country": "US"
          }
        ],
        "groups": [
          {
            "id": "group_1",
            "line_item_ids": ["line_1", "line_2"],
            "selected_option_id": "ship_ground",
            "options": [
              {
                "id": "ship_ground",
                "title": "Ground (3-5 days)",
                "description": "Estimated Delivery: Fri 5/8", // Maximum length: 200 characters.
                "totals": [ { "type": "total", "amount": 600 } ]
              },
              {
                "id": "ship_express",
                "title": "Express (1-2 days)",
                "description": "Estimated Delivery: Wed 5/6", // Maximum length: 200 characters.
                "totals": [ { "type": "total", "amount": 1600 } ]
              }
            ]
          }
        ]
      }
    ]
  }
  // ... other fields like ucp, status, messages, links
}

Pełne dane obiektu płatności

Żądanie: gdy kupujący kliknie „Zapłać za pomocą GPay”, Google wysyła pełny obiekt płatności z aktualnymi informacjami (w tym pełny adres dostawy i dane kontaktowe kupującego).

// Request Example: full checkout object hydration for multiple items.
{
  "buyer": {
    "first_name": "John",
    "last_name": "Buyer",
    "email": "johnbuyer@example.com",
    "phone_number": "+18888888888"
  },
  "line_items": [
    {
      "id": "line_1",
      "item": { "id": "product_12345" },
      "quantity": 1
    },
    {
      "id": "line_2",
      "item": { "id": "product_67890" },
      "quantity": 1
    }
  ],
  "fulfillment": {
    "methods": [
      {
        "id": "method_shipping",
        "type": "shipping",
        "line_item_ids": ["line_1", "line_2"],
        "selected_destination_id": "addr_1",
        "destinations": [
          {
            "id": "addr_1",
            "first_name": "Alice",
            "last_name": "Receiver",
            "street_address": "1600 Amphitheatre Pkwy",
            "extended_address": "Suite #60",
            "address_locality": "Mountain View",
            "address_region": "CA",
            "postal_code": "94043",
            "address_country": "US",
            "phone_number": "+18888888888"
          }
        ],
        "groups": [
          {
            "id": "group_1",
            "selected_option_id": "ship_ground"
          }
        ]
      }
    ]
  }
}

Odpowiedź: w razie potrzeby ponownie obliczasz podatki i opcje dostawy oraz zwracasz pełny obiekt płatności.

// Response Example: Session after full hydration with multiple items.
{
  "ucp": {
    "version": "2026-01-23",
    "capabilities": {
      "dev.ucp.shopping.checkout": [ { "version": "2026-01-23" } ],
      "dev.ucp.shopping.fulfillment": [ { "version": "2026-01-23", "extends": "dev.ucp.shopping.checkout" } ]
    },
    "payment_handlers": {
      "com.google.pay": [
        {
          "id": "8c9202bd-63cc-4241-8d24-d57ce69ea31c",
          "version": "2026-01-23",
          "spec": "https://pay.google.com/gp/p/ucp/2026-01-23/",
          "schema": "https://pay.google.com/gp/p/ucp/2026-01-23/schemas/config.json",
          "config": {
            "api_version": 2,
            "api_version_minor": 0,
            "environment": "TEST",
            "merchant_info": {
              "merchant_name": "Example Merchant",
              "merchant_id": "KWMZPRLQFTYNXSDB",
              "merchant_origin": "checkout.merchant.com"
            },
            "allowed_payment_methods": [
              {
                "type": "CARD",
                "parameters": {
                  "allowed_auth_methods": [ "PAN_ONLY", "CRYPTOGRAM_3DS" ],
                  "allowed_card_networks": [ "AMEX", "DISCOVER", "JCB", "MASTERCARD", "VISA" ],
                  "billing_address_required": true,
                  "billing_address_parameters": {
                    "format": "FULL",
                    "phone_number_required": true
                  }
                },
                "tokenization_specification": {
                  "type": "PAYMENT_GATEWAY",
                  "parameters": {
                    "gateway": "example",
                    "gatewayMerchantId": "exampleGatewayMerchantId"
                  }
                }
              }
            ]
          }
        }
      ]
    }
  },
  "id": "da2e25ec-eef8-41b7-a439-4e62dea41bdc",
  "status": "ready_for_complete",
  "currency": "USD",
  "buyer": {
    "first_name": "John",
    "last_name": "Buyer",
    "email": "johnbuyer@example.com",
    "phone_number": "+18888888888"
  },
  "line_items": [
    {
      "id": "line_1",
      "item": {
        "id": "product_12345",
        "title": "Running Shoes",
        "price": 10000,
        "image_url": "https://merchant.example.com/images/product_12345.png"
      },
      "quantity": 1,
      "totals": [
        { "type": "subtotal", "amount": 10000 },
        { "type": "total", "amount": 10000 }
      ]
    },
    {
      "id": "line_2",
      "item": {
        "id": "product_67890",
        "title": "T-Shirt",
        "price": 2500,
        "image_url": "https://merchant.example.com/images/product_67890.png"
      },
      "quantity": 1,
      "totals": [
        { "type": "subtotal", "amount": 2500 },
        { "type": "total", "amount": 2500 }
      ]
    }
  ],
  "totals": [
     { "type": "subtotal", "display_text": "Subtotal", "amount": 12500 },
     { "type": "fulfillment", "display_text": "Ground Shipping", "amount": 600 },
     { "type": "tax", "display_text": "Estimated Tax", "amount": 1120 },
     { "type": "total", "display_text": "Total", "amount": 14220 }
  ],
  "fulfillment": {
    "methods": [
      {
        "id": "method_shipping",
        "type": "shipping",
        "line_item_ids": ["line_1", "line_2"],
        "selected_destination_id": "addr_1",
        "destinations": [
          {
            "id": "addr_1",
            "first_name": "Alice",
            "last_name": "Receiver",
            "street_address": "1600 Amphitheatre Pkwy",
            "extended_address": "Suite #60",
            "address_locality": "Mountain View",
            "address_region": "CA",
            "postal_code": "94043",
            "address_country": "US",
            "phone_number": "+18888888888"
          }
        ],
        "groups": [
          {
            "id": "group_1",
            "line_item_ids": ["line_1", "line_2"],
            "selected_option_id": "ship_ground",
            "options": [
              {
                "id": "ship_ground",
                "title": "Ground (3-5 days)",
                "description": "Estimated Delivery: Fri 5/8", // Maximum length: 200 characters.
                "totals": [ { "type": "total", "amount": 600 } ]
              },
              {
                "id": "ship_express",
                "title": "Express (1-2 days)",
                "description": "Estimated Delivery: Wed 5/6", // Maximum length: 200 characters.
                "totals": [ { "type": "total", "amount": 1600 } ]
              }
            ]
          }
        ]
      }
    ]
  },
  "links": [
    {
      "type": "terms_of_service",
      "url": "https://m.com/terms",
      "title": "Terms of Service"
    },
    {
      "type": "privacy_policy",
      "url": "https://m.com/privacy",
      "title": "Privacy Policy"
    }
  ]
}

Zakończ sesję płatności

Ten punkt końcowy umożliwia dokończenie sesji płatności i złożenie zamówienia. Powinna zwrócić ukończoną sesję płatności i zawierać informacje o zamówieniu. Przetwarzanie płatności powinno rozpocząć się po otrzymaniu tego wywołania.

Żądanie: Google wysyła wybraną formę płatności z programu obsługi płatności, w tym dane logowania (np. dane tokenizacji Google Pay) i sygnały ryzyka dotyczące kupującego, aby umożliwić Ci wykrywanie oszustw. Zawartość tokena zależy od dostawcy usług płatniczych.

{
  "payment": {
    "instruments": [
      {
        "billing_address": {
          "first_name": "John",
          "last_name": "Buyer",
          "street_address": "100 Main St",
          "extended_address": "Apt 4B",
          "address_locality": "San Francisco",
          "address_region": "CA",
          "postal_code": "94105",
          "address_country": "US",
          "phone_number": "+18888888888"
        },
        "credential": {
          "token": "examplePaymentMethodToken",
          "type": "PAYMENT_GATEWAY"
        },
        "display": {
          "brand": "VISA",
          "description": "Visa •••• 1234",
          "last_digits": "1234"
        },
        "handler_id": "8c9202bd-63cc-4241-8d24-d57ce69ea31c",
        "id": "94e7fee0-1a82-4c2a-9ef4-0861a3c829b2",
        "selected": true,
        "type": "card"
      }
    ]
  },
  "signals": {
    "com.google.authentication_triggered": "",
    "com.google.authorization_processed_with_3ds": "",
    "com.google.avs_full_result": "",
    "com.google.cvv_result": "",
    "com.google.ip_address": "203.0.113.1",
    "dev.ucp.buyer_id": "ec46fedc6aad89d3660a50a61d00b4908fd160ecf5dda6d49ed41a605c5b180a",
    "dev.ucp.buyer_ip": "203.0.113.1"
  }
}

Jeśli do sfinalizowania płatności wymagane są informacje, które nie zostały podane w sesji płatności, możesz uniemożliwić sfinalizowanie płatności i poprosić o te informacje, zwracając w odpowiedzi stan „niekompletny”.

Jeśli Google może zebrać brakujące informacje za pomocą pól zdefiniowanych przez UCP (np. adres e-mail kupującego), ustaw wartość status na incomplete i uwzględnij co najmniej 1 komunikat w tablicy messages z wartością severity ustawioną na recoverable, wskazującą, jakich informacji brakuje.

{
  "id": "da2e25ec-eef8-41b7-a439-4e62dea41bdc",
  "status": "incomplete",
  "messages": [
    {
      "type": "error",
      "code": "missing_buyer_info",
      "severity": "recoverable",
      "content": "Buyer email is required"
    },
    {
      "type": "error",
      "code": "missing_fulfillment_info",
      "severity": "recoverable",
      "content": "Select delivery window for your purchase"
    }
  ]
}

Po otrzymaniu instrumentu płatniczego Google Pay musisz:

  1. Sprawdź moduł obsługi: upewnij się, że handler_id odpowiada modułowi obsługi płatności Google Pay zdefiniowanemu w konfiguracji.
  2. Wyodrębnij token: pobierz wygenerowany token formy płatności z payment.instruments[0].credential.token.
  3. Przetwarzanie płatności: użyj tokena i szczegółów transakcji, aby zrealizować płatność. Szczegółową dokumentację dotyczącą specyfikacji tokenizacji i jej obsługi znajdziesz w dokumentacji interfejsu Google Pay API.

Odpowiedź: jeśli można dokończyć płatność i została ona przetworzona, zwracasz pełny obiekt płatności wskazujący, że zamówienie zostało zrealizowane, w tym potwierdzoną formę płatności (z metadanymi formy płatności i adresem rozliczeniowym, bez poufnego tokena credential lub signals), identyfikator zamówienia i adres URL zamówienia.

{
  "ucp": {
      "version": "2026-01-23",
      "capabilities": [...]
  },
  "id": "da2e25ec-eef8-41b7-a439-4e62dea41bdc",
  "status": "completed",

  // ... other fields (line_items, currency, etc.)

  "payment": {
    "instruments": [
      {
        "id": "94e7fee0-1a82-4c2a-9ef4-0861a3c829b2",
        "handler_id": "8c9202bd-63cc-4241-8d24-d57ce69ea31c",
        "type": "card",
        "selected": true,
        "display": {
          "brand": "VISA",
          "description": "Visa •••• 1234",
          "last_digits": "1234"
        },
        "billing_address": {
          "first_name": "John",
          "last_name": "Buyer",
          "street_address": "100 Main St",
          "extended_address": "Apt 4B",
          "address_locality": "San Francisco",
          "address_region": "CA",
          "postal_code": "94105",
          "address_country": "US",
          "phone_number": "+18888888888"
        }
      }
    ]
  },
  "order": {
    "id": "ORD1773956535.2727807",
    // Example customer-facing order number
    "label": "#100",
    "permalink_url": "https://merchant.example.com/orders/789"
  }
}

Anulowanie sesji płatności

Ten punkt końcowy anuluje sesję płatności.

  • Punkt końcowy: POST /checkout-sessions/{id}/cancel

Żądanie: Google wysyła identyfikator sesji płatności.

Odpowiedź: zwracasz pełny obiekt płatności ze stanem zaktualizowanym do canceled.

Obsługa błędów

Pełne wytyczne dotyczące formatowania komunikatów o błędach i różnic między błędami protokołu a błędami logiki biznesowej znajdziesz w omówieniu kodów błędów.

Nieodwracalny błąd

W przypadku wersji 2026-01-23, gdy nieodwracalny błąd logiki biznesowej uniemożliwia utworzenie sesji płatności (np. wszystkie produkty są niedostępne), zwróć kod HTTP 200 OK.

W wersji 2026-01-23 musisz wskazać niepowodzenie terminala, pomijając identyfikator sesji płatności i określając "severity": "unrecoverable" w tablicy messages. Informuje to Google, że żądanie było prawidłowe, ale reguła biznesowa zablokowała utworzenie sesji.

HTTP/1.1 200 OK
Content-Type: application/json

{
  "ucp": {
    "version": "2026-01-23"
  },
  "messages": [
    {
      "type": "error",
      "code": "out_of_stock",
      "content": "All requested items are currently out of stock",
      "severity": "unrecoverable"
    }
  ],
  "continue_url": "https://merchant.com/"
}