Address recommendations without breaking checkout state

Treat address validation as a suggestion workflow with explicit user choices, stale-response protection, and controlled persistence.

Znode 10GuideIntermediateGCG engineering guide
In this guide
Entered address Current validation User choice Accepted address Recalculate delivery
A recommendation should become checkout state only after the correct user choice and persistence step.

The helpful suggestion that erases a suite number

A buyer enters a delivery address with a building and suite. An external validator returns a standardized version. The checkout replaces the form immediately, and the suite disappears. The service improved one representation while losing information that mattered to the shipment.

Keep the entered address, suggested address, and accepted address as distinct states. A provider recommendation is evidence for the user to consider, not automatic permission to overwrite their input. Decide which changes can be accepted silently, if any, and which require explicit comparison under the business's delivery policy.

Validate the current input revision

Assign a revision to the address being edited. Send a normalized copy for validation and associate the response with that revision. If the buyer changes the form while the request is in flight, discard the old recommendation rather than presenting it as a suggestion for the new address.

Preserve fields the provider does not understand or return. Country and region identifiers may need mapping to the commerce platform's model; display labels are not always suitable keys. Resolve mappings through a bounded, version-appropriate adapter and distinguish unsupported countries from invalid addresses.

Model the recommendation lifecycle

AddressRecommendationState keeps the entered address separate from a recommendation, tags responses with the input revision, and accepts a deliberate choice. An edit invalidates earlier suggestions. choose returns the selected address and consumes the recommendation so it cannot be applied twice.

Call beginValidation before the provider request and receive after mapping its result. Preserve required suite and company information during that mapping. Send choose's result to the existing authorized checkout address-save path, then invalidate shipping and tax calculations that depend on the destination.

checkout/address-recommendation-state.ts typescript

export type Address = Readonly<{
line1: string; line2: string; city: string;
region: string; postalCode: string; country: string;
}>;
export type Recommendation = Readonly<{
revision: number; original: Address; suggested: Address;
}>;
export class AddressRecommendationState {
private revision = 0;
private entered: Address;
private recommendation: Recommendation | null = null;
constructor(initial: Address) { this.entered = { ...initial }; }
edit(address: Address): number {
this.entered = { ...address };
this.recommendation = null;
return ++this.revision;
}
beginValidation(): Readonly<{ revision: number; address: Address }> {
return { revision: this.revision, address: { ...this.entered } };
}
receive(revision: number, suggested: Address): boolean {
if (revision !== this.revision) return false;
this.recommendation = {
revision, original: { ...this.entered }, suggested: { ...suggested }
};
return true;
}
choose(useSuggestion: boolean, allowOriginal: boolean): Address {
const result = this.recommendation;
if (!result || result.revision !== this.revision)
throw new Error("Validate the current address first.");
if (!useSuggestion && !allowOriginal)
throw new Error("This delivery requires a corrected address.");
const chosen = useSuggestion ? result.suggested : result.original;
this.entered = { ...chosen };
this.recommendation = null;
++this.revision;
return { ...chosen };
}
}
// Construct the suggested Address after mapping provider fields and preserving
// required company/suite data. Save only after the buyer chooses.

Persist once the choice is settled

Avoid saving both the original and suggestion as new address-book entries during the same interaction. Decide whether the buyer is editing an existing address, creating one, or using a checkout-only address. That identity needs to survive the recommendation flow.

After the accepted address is saved, invalidate shipping methods, rates, tax estimates, and other calculations that depend on it. Do not retain a shipping quote for the old destination merely because the address form is now valid. Billing and shipping addresses also need separate state when the buyer has chosen different locations.

Test the full checkout lifecycle

Use a fake validator that can return an exact match, a changed street, multiple candidates, no candidate, unsupported country, slow response, and failure. Test accepting the suggestion, keeping the original where allowed, canceling, editing again, and submitting twice.

Check that a late response cannot replace a newer address. Verify suite and company fields, country and region mappings, existing address IDs, and address-book duplication. Navigate the recommendation interface with a keyboard and confirm focus returns to a useful control. Finally verify that shipping and totals are recalculated from the accepted address rather than the last submitted form snapshot.

  • Do not expose provider credentials to the browser.
  • Keep address payloads out of routine diagnostic logs.
  • Differentiate user validation errors from dependency failures.

Explain uncertainty without adding friction

Show the two addresses in a clear comparison and identify what changed. Avoid a generic 'corrected address' label when the provider has only offered a recommendation. The buyer may know a delivery detail that is absent from the external service.

A good integration assists the buyer while maintaining a coherent checkout state. The underlying service call is only one step. Preserved input, current-response checks, explicit choice, and correct recalculation are what turn that call into a reliable purchasing experience.

References and further reading

Bring your next engineering question.

Improve checkout implementation

Explore how GCG can help

Independent guidance from GCG. Znode is a trademark of its owner. Examples use fictional data and are not official platform documentation. Suggest a correction.