Skip to content

Checkout blocker: invalid separate billing telephone traps customer on shipping after returning from payment #41445

Open

Description

@n2diving-net

Summary

Magento can strand a customer on the shipping step when a previously selected separate billing address contains an invalid telephone number. The customer can repeatedly edit the visible shipping telephone number, but shipping submission continues to fail because Magento restores and submits the invalid billing telephone number. The billing form is no longer visible at that step, and clicking Review & Payments did not reopen it in our test.

The verified trigger is an invalid telephone number in a separately selected billing address, followed by returning from payment to shipping. It is not simply an invalid shipping telephone number on a fresh guest checkout.

The critical sequence is:

Valid shipping is accepted → the customer enters a separate billing address with an invalid telephone number → billing Update is rejected → the customer returns to shipping → Next restores the invalid selected billing address and submits it with shipping, but the resulting error message regarding an invalid telephone number does not indicate the error is with the previously entered billing telephone number → changing the visible shipping telephone number does not repair billing → checkout repeatedly rejects the billing telephone number while its editor is unavailable on the current shipping step.

This is an error-recovery and navigation defect. The customer needs a usable route to correct the billing telephone actually being rejected, while being mislead that the error is in the shipping telephone.

Merchant history and business consequences

I am responsible for managing a significant e-commerce site that has used Magento since version 1. I have been aware of intermittent customer reports of this checkout problem for literally years, going back as far as the introduction of Magento 2. Customers would report that their phone number was rejected and that changing it did not help. We could not reliably reproduce their experience.

The investigation combined extensive checkout-event telemetry, customer-support history, source inspection, AI-assisted diagnosis, and isolated code tests. Subsequent browser testing on an unpatched Luma installation identified the reproducible separate-billing recovery failure described below.

Our support history includes customers who reported trying multiple phone formats, editing both addresses, trying different addresses, and repeatedly failing to complete checkout. In one case, I subsequently placed the order from a separate session. That kind of intermittent behavior makes the problem easy to dismiss when a developer's fresh-session test succeeds.

The potential commercial consequences are significant:

  • Customers can be prevented from completing otherwise legitimate purchases.
  • Repeatedly correcting the visible field does not necessarily correct the submitted data.
  • Customers may abandon the purchase, buy elsewhere, or lose confidence in the store.
  • Support staff may spend substantial time recommending changes that do not affect the stale value.
  • Ordinary analytics may show an abandoned checkout without revealing the underlying recovery failure.

Customers who contact support are the visible cases. We do not have a reliable count of those who leave without contacting us. Nevertheless, a defect that prevents a motivated customer from completing checkout deserves serious attention.

Related historical report

The symptoms resemble issue #3374, opened February 11, 2016.

That report describes a customer returning to shipping after an error, correcting the address, and receiving the same error because billing retained the original problematic data.

The original reporter identified Magento 2.0.2. Maintainers could not reproduce the problem and closed the ticket. A later contributor supplied reproduction steps for Magento 2.0.4 using standard payment methods. Further reports continued afterward.

The historical similarity is substantial. This report also supplies a current, directly testable client-side mechanism; it does not depend on assuming that every historical complaint had an identical cause.

Preconditions and environment

  • Magento Open Source 2.4.9 with the Luma theme and sample catalog data, on a dedicated installation supplied as an unmodified test store.
  • Guest checkout with a physical product: Fusion Backpack (SKU 24-MB02).
  • Flat Rate shipping and Check / Money order payment were available.
  • The customer first reaches Review & Payments, then explicitlyenters a separate billing address containing an invalid telephone number.

Steps to reproduce

Follow the billing-selection and return-to-shipping steps closely. A fresh shipping-only invalid-phone test recovers normally and does not demonstrate this defect.

  1. Start a guest checkout with a physical product.
  2. Enter valid shipping details, including a valid telephone number such as +1 (305) 555-0100.
  3. Select Flat Rate shipping and click Next. Confirm that Review & Payments is displayed.
  4. Under Check / Money order, uncheck My billing and shipping address are the same.
  5. Enter complete billing details. For a controlled test, the name and postal address may match shipping, but enter N/A in the billing Phone Number field.
  6. Click Update. Observe the billing telephone validation error. In our test, the billing details view nevertheless displayed the selected address with telephone N/A and an Edit button.
  7. In the order summary, click the pencil/Edit control beside Ship To to return to the shipping step. Do not correct billing first and do not clear checkout state.
  8. Replace the visible shipping telephone number with another valid number, such as +1 (305) 555-0101, and click Next.
  9. Observe that shipping submission is rejected because the billing telephone number is invalid.
  10. Change the shipping telephone number again, for example to 3055550102, and click Next. The billing-phone rejection repeats.
  11. Try clicking Review & Payments in the checkout progress bar. In our test it did not reopen the billing form; the customer remained on shipping.

Expected result

A billing telephone validation failure must always leave the customer with an accessible way to edit the rejected billing address telephone number field. Returning to shipping must not strand the customer behind a validation error for a field unavailable at that step.

Actual result

After the billing Update attempt, Magento displayed:

The billing address contains invalid data: Invalid Phone Number. Please use 0-9, +, -, (, ), ., / and space.

After returning to shipping and submitting a valid shipping phone, Magento displayed:

The shipping information was unable to be saved. Error: "The billing address contains invalid data: Invalid Phone Number. Please use 0-9, +, -, (, ), ., / and space."

A second different valid shipping phone produced the same billing rejection. The billing editor was not visible at the shipping step, and clicking the payment-step heading did not reopen it.

The problem is not that a shipping edit ought to repair a separate billing address. It is that the selected invalid billing state is resubmitted while ordinary checkout navigation provides no effective route back to its editor in this flow. This can produce repeated failed attempts and purchase abandonment.

Additional information

Relevant core behavior

Paths below are relative to app/code/Magento/Checkout/view/frontend/web/js/ in a source checkout, or vendor/magento/module-checkout/view/frontend/web/js/ in a Composer installation.

1. Billing is selected and stored before server validation succeeds

In view/billing-address.js, updateAddress() selects the new billing address and records its selection and form data before calling updateAddresses():

newBillingAddress = createBillingAddress(addressData);
selectBillingAddress(newBillingAddress);
checkoutData.setSelectedBillingAddress(newBillingAddress.getKey());
checkoutData.setNewCustomerBillingAddress(addressData);

The failed billing request is reported by action/set-billing-address.js. Its failure handler reports the error and stops the loader; it does not roll back the stored selection. The invalid address remained selected in our browser test.

2. Shipping Next clears billing, then restores the selected invalid address

In view/shipping.js, setShippingInformation() contains:

if (this.validateShippingInformation()) {
    quote.billingAddress(null);
    checkoutDataResolver.resolveBillingAddress();
    // ...
}

This reset explains why a fresh shipping-only correction recovers.

However, model/checkout-data-resolver.js restores an explicitly selected new billing address from stored checkout data:

selectedBillingAddress = checkoutData.getSelectedBillingAddress();
newCustomerBillingAddressData = checkoutData.getNewCustomerBillingAddress();

if (selectedBillingAddress) {
    if (selectedBillingAddress === 'new-customer-billing-address' && newCustomerBillingAddressData) {
        selectBillingAddress(createBillingAddress(newCustomerBillingAddressData));
    }
    // ...
}

Consequently, clearing the billing observable does not remove or correct the invalid selected billing data. The resolver restores it.

3. The shipping processor includes that billing address

model/shipping-save-processor/default.js includes both quote.shippingAddress() and quote.billingAddress() in the shipping-information request. Changing shipping does not change a separately selected billing address. The observed server error specifically identifies billing.

These are source-inspection findings consistent with the visible browser behavior.

4. The normal progress navigation cannot reopen payment from shipping

In model/step-navigator.js, isProcessed(code) compares the requested step's position to the currently active step:

return activeItemIndex > requestedItemIndex;

And navigateTo() returns without navigating when that check fails:

if (!this.isProcessed(code)) {
    return;
}

After returning to shipping, payment is ahead of the active step even though it was previously visited. This is consistent with the observed inability to reopen payment through its progress heading. Advancing with Next is blocked by the restored invalid billing address.

The required fix is a billing-error recovery path, not unconditional address synchronization. A replacement needs to:

  • Keep a rejected billing address editable, with the actual invalid field identified.
  • Provide an explicit, working way to edit billing when its validation blocks submission from shipping, including this return-from-payment flow.
  • Preserve the customer's separate billing details until the customer corrects or explicitly replaces them.
  • Update the selected billing data used by the resolver after correction, so the rejected value is not restored on retry.
  • Successfully save corrected shipping and refresh totals and payment availability before allowing order placement; merely jumping past a failed shipping save is insufficient.
  • Cover state restored from checkout storage as well as the current in-memory address.

These are patch requirements and a proposed direction, not claims that replacement code has been implemented or tested.

Regression coverage requested

  1. The exact separate-billing failure and return-to-shipping sequence above.
  2. Successful recovery by editing the rejected billing phone through the provided UI.
  3. Preservation of legitimate separate billing details.
  4. Multiple failed retries and subsequent successful correction.
  5. Shipping changes that affect rates or totals during recovery.
  6. Switching between same-as-shipping and separate billing.
  7. Guest and saved-customer-address flows, and checkout-state restoration after reload.
  8. The negative control: a fresh invalid shipping phone followed by a valid correction continues normally.

The guest separate-billing failure and fresh-shipping negative control were exercised in the browser. The broader integration cases remain requested coverage, not completed tests.

Requested maintainer action

Please reproduce the separate billing selection → rejected billing Update → return to shipping sequence before assessing reproducibility. Testing only an invalid shipping phone in a fresh checkout misses the verified conditions.

We request confirmation of this recovery/navigation defect, review of a repair that preserves separate billing information, an end-to-end regression test, and backport consideration for affected supported releases.

Proposed release note

Allow customers to correct an invalid separately selected billing address when its validation blocks the shipping step after returning from payment, without losing billing information or bypassing shipping validation.

Triage and priority

  • Severity: S1 — Affects critical functionality and forces users to employ a workaround.

Checkout is critical functionality. Once this path is triggered, repeatedly editing the visible shipping telephone number cannot repair the hidden billing value. Recovering requires access to billing correction or a checkout-state workaround that is not apparent from the ordinary shipping form.

Activity

  1. m2-assistant commented on Oct 8, 2026

    @m2-assistant

    Hi @n2diving-net. Thank you for your report.
    To speed up processing of this issue, make sure that the issue is reproducible on the vanilla Magento instance following Steps to reproduce.


    Join Magento Community Engineering Slack and ask your questions in #github channel.
    ⚠️ According to the Magento Contribution requirements, all issues must go through the Community Contributions Triage process. Community Contributions Triage is a public meeting.
    🕙 You can find the schedule on the Magento Community Calendar page.
    📞 The triage of issues happens in the queue order. If you want to speed up the delivery of your contribution, join the Community Contributions Triage session to discuss the appropriate ticket.

  2. github-jira-sync-bot commented on Oct 8, 2026

    @github-jira-sync-bot

    ❌ Something went wrong. Cannot create Jira issue.

  3. changed the title [-]Checkout blocker: correcting shipping leaves stale invalid billing data in subsequent requests[/-] [+]Checkout blocker: invalid separate billing telephone traps customer on shipping after returning from payment[/+] on Oct 8, 2026
  4. bluefairydevelopment commented on Oct 27, 2026

    @bluefairydevelopment

    Reproduced on 2.4-develop, as a guest exactly as described. The same trap also applies to a logged-in customer whose saved default billing address is invalid: checkout picks it automatically and every shipping Next fails, from a new cart. Fix in #41726: a rejected billing address is deselected and its form reopened, and a rejected default billing address is replaced by the shipping address with a message to correct it. Thanks n2diving-net for the thorough write-up.

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions