Skip to content

fix(checkout): defer the guest logout while PUI payment instructions are pending - #827

Open
Max Stegmeyer (mstegmeyer) wants to merge 1 commit into
trunkfrom
fix/pui-guest-logout-finish-page
Open

Max Stegmeyer (mstegmeyer) wants to merge 1 commit into
trunkfrom
fix/pui-guest-logout-finish-page

Conversation

@mstegmeyer

Copy link
Copy Markdown
Contributor

1. Why is this change necessary?

The Pay Upon Invoice finish page is the only checkout finish page that is not self-contained: when Ratepay has not returned the bank details yet, it renders a polling widget that needs further authenticated requests. The automatic guest logout runs between loading and rendering that page, so the polling ran into a destroyed session and the customer landed on the order edit page with a "payment declined" error — on a payment that had in fact been captured.

The fix shipped for this in 10.1.1 cancelled the logout for every PUI order. That unblocks the page, but it silently voids the merchant's setting forever.

2. What does this change do, exactly?

It defers the logout rather than cancelling it: the suppression now applies only while the polling widget is actually rendered, so the logout runs as configured on the reload that shows the instructions.

Whether polling is pending is no longer inferred from "no instructions present", because a third case exists between the two: a completed payment that came back without any instructions. That one used to throw straight through the page loader, and now renders the page with a notice instead.

Separately, a voided PayPal order reported "not ready" instead of failing, so a genuinely declined payment kept polling indefinitely. It now raises a terminal exception, which the storefront's existing error path already handles.

3. Describe each step to reproduce the issue or behaviour.

Enable "log out guest customers after order" under Settings → Cart, then order as a guest with Pay Upon Invoice and let the payment instructions arrive late enough for the finish page to show the polling spinner.

4. Please link to the relevant issues (if any).

closes shopware/shopware#7962

5. Checklist

  • I have written tests and verified that they fail without my change
  • I have created an entry in the CHANGELOG.md files with all necessary user information about my changes
  • This change has comments for package types, values, functions, and non-obvious lines of code
  • I have read the contribution requirements and fulfill them.

The PUI finish page is the only one that is not self-contained: when the
instructions are not back from Ratepay yet it renders a polling widget that
needs two further authenticated requests. The automatic guest logout runs
between loading and rendering that page, so the polling died in a destroyed
session and the customer ended up on the order edit page with a payment
declined error on a payment that had actually been captured.

The suppression that was shipped for this cancelled the logout for every PUI
order, which honours the finish page but silently voids the merchant setting
forever. Suppress it only while the polling widget is actually rendered, so
the logout happens on the reload that shows the instructions.

A voided PayPal order also reported "not ready" instead of failing, so a
genuinely declined payment polled indefinitely. It now throws a dedicated
terminal exception.
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 17, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-17T18:11:58.696498Z f86b1f2 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f86b1f2f42

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "Codex (@codex) review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "Codex (@codex) address that feedback".

Comment on lines +71 to +72
} catch (MissingPaymentInstructionsException $e) {
// paid, but PayPal sent no instructions, so render the page without them

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Reload the finish page when polling finds missing instructions

When the initial finish-page request sees a pending order but a later polling request sees COMPLETED without instructions, MissingPaymentInstructionsException is returned by the polling endpoint as HTTP 404. The existing polling client treats every status other than 417 as a payment failure and redirects to errorUrl, so this new catch is never reached and a successfully completed payment is presented as declined. The polling response must distinguish this terminal successful-without-instructions case and reload the finish page instead.

Useful? React with 👍 / 👎.

Comment on lines +71 to +72
} catch (MissingPaymentInstructionsException $e) {
// paid, but PayPal sent no instructions, so render the page without them

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Mark completed payments paid before accepting missing details

When PayPal reports COMPLETED without instructions, this catch now treats the result as a terminal, successfully renderable finish page, but PUIInstructionsFetchService throws MissingPaymentInstructionsException before calling the transaction state's paid() transition. The transaction therefore remains authorized/in-progress despite the completed payment, and the scheduled fetch task continues selecting it while its message handler does not catch this exception, producing repeated failures and preventing downstream paid-order processing. Finalize the transaction state before handling missing instructions as a nonfatal display condition.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

PUI does not reach finish page, if guest customer logout after checkout is active

1 participant