Skip to content

Payment token re-initialization fails with 400 Bad Request after checkout cancellation #789

@xeniajensen

Description

@xeniajensen

Which component is this issue related to?

Checkout

Which Umbraco Commerce version are you using? (Please write the exact version, example: 10.1.0)

16.4.0

Bug summary

The /pay/{token} endpoint returns 400 Bad Request when attempting to re-initialize payment after a checkout session has been canceled, even though a new token is successfully generated.

Specifics

  • Umbraco Commerce Version: 16.4.0
  • Component: Checkout
  • Payment Gateway: Nets Easy OneTime Payment (hosted checkout, Framed mode)
  • API Endpoint: /umbraco/commerce/storefront/api/v1/checkout/{orderId}/

The cancellation is triggered automatically by the DIBS payment gateway when the iframe is unloaded. Token generation always succeeds, but /pay/{token} fails on re-initialization.

Steps to reproduce

  1. User reaches payment step and payment token is generated via GET /checkout/{orderId}/token → Success
  2. Payment iframe loads GET /checkout/{orderId}/pay/{token} → Success (payment form displays)
  3. User navigates back to previous step
  4. Payment gateway automatically calls /pay/{token}/canceled when iframe unloads
  5. User navigates forward to payment step again
  6. New payment token is generated via GET /checkout/{orderId}/token → Success
  7. Payment iframe attempts to load GET /checkout/{orderId}/pay/{newToken}400 Bad Request

Expected result / actual result

Expected Behavior

After a checkout session is canceled, we should be able to:

  1. Generate a new payment token via /token endpoint
  2. Successfully load the payment form via /pay/{token} endpoint using the new token

Actual Behavior

  • First payment initialization works: GET /checkout/{orderId}/token200 OK, GET /checkout/{orderId}/pay/{token}200 OK
  • After navigation away and return: GET /checkout/{orderId}/token200 OK (new token), but GET /checkout/{orderId}/pay/{token}400 Bad Request

Questions

  1. Is it expected that /pay/{token} returns 400 after a checkout session has been canceled, even with a newly generated token?
  2. Is there a way to reset the checkout session state or clear an existing checkout session programmatically?
  3. What is the recommended pattern for handling user navigation in multi-step checkout flows with hosted payment?

Dependencies

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions