fix(checkout): preserve full billing address when country changes - #14038
Open
detail-app[bot] wants to merge 1 commit into
Open
fix(checkout): preserve full billing address when country changes#14038detail-app[bot] wants to merge 1 commit into
detail-app[bot] wants to merge 1 commit into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
frankie567
approved these changes
Aug 31, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Detail bug report: View on Detail
Summary
Related Issue: polarsource/feedback#417
When a user changes the billing country dropdown in the checkout form, the watcher sent only
{ country: newCountry }to the server instead of the full billing address. The server replaces the entirecustomer_billing_addresson update, so all other fields (line1, city, postal_code, state) were dropped from server state — causing incorrect tax calculations and address data loss on page refresh.What
CheckoutForm.tsx: The country-change watcher now spreads...customerBillingAddress(all existing form address fields) and overridescountry: newCountry, mirroring the pattern already used by the other-address-field watcher branch. When the state field is reset (switching between fixed-state countries like US/CA),state: ''is included in the payload so the server receives the reset value consistent with the form UI.CheckoutForm.test.tsx: Updated the existing "resets state field when country changes" test to assert theupdate()payload includes all address fields (not just country). Added a new test verifying all fields are sent when changing between two non-fixed-state countries (no state reset).Why
The country-change watcher was inconsistent with the other address field watchers: the country path sent only
{ country }while the other fields spread the fullcustomerBillingAddress. Because the server does a full replace (checkout.customer_billing_address = checkout_update.customer_billing_address), sending only country truncated the stored address. This caused:The bug was introduced in
ba33eac70d(PR #4060), which added the watcher pattern for address field changes.How
The fix is a single client-side change: spread
customerBillingAddressin the country-change payload, the same way the other-address-field branch already does. No server-side changes are needed — the server's full-replace semantics are correct when the client sends the full address. TheshouldResetStatecondition was extracted into a variable to avoid duplicating the state-reset check between theresetFieldcall and the payload construction.Testing
state: '') and the new "sends all billing address fields when country changes without state reset" (verifies fields are preserved when switching SE → DE). The full checkout package suite (389 tests) passes with no regressions.tsc --noEmitandoxfmt --checkboth pass clean.line1,postal_code,city,state,country), (2) after page refresh the form fields were still populated from server state, and (3) the server API confirmed the full address was stored. Also tested with a paid product — the client correctly sent the full address on both US and FR country changes (confirmed via request capture); server-side persistence couldn't be fully verified for the paid product because the dev Stripe key is a placeholder, but a direct API test on the free product confirmed the server stores and returns the full address on country change.Checklist
uv run task lint && uv run task lint_types)Automatic Fixes PRs can be configured here.