diff --git a/.changeset/customer-account-exaf-addresses.md b/.changeset/customer-account-exaf-addresses.md new file mode 100644 index 0000000000..1afaa066e0 --- /dev/null +++ b/.changeset/customer-account-exaf-addresses.md @@ -0,0 +1,5 @@ +--- +'@shopify/ui-extensions': minor +--- + +Add structured extended address fields to Customer Account order address APIs. diff --git a/packages/ui-extensions/docs/surfaces/customer-account/build-docs.mjs b/packages/ui-extensions/docs/surfaces/customer-account/build-docs.mjs index 70c4dd6c01..cb9ee297e6 100644 --- a/packages/ui-extensions/docs/surfaces/customer-account/build-docs.mjs +++ b/packages/ui-extensions/docs/surfaces/customer-account/build-docs.mjs @@ -68,6 +68,100 @@ const cleanupTempFiles = async (tempFiles) => { ); }; +const customerAccountMailingAddressFields = [ + { + filePath: 'src/surfaces/customer-account/api/shared.ts', + syntaxKind: 'PropertySignature', + name: 'extendedFields', + value: 'AddressExtendedFields', + description: + 'Structured address components for countries and regions that collect them. ' + + "The value is `undefined` when structured address data isn't available " + + 'for the order address. Individual fields are `null` when Shopify has ' + + "a structured address record but a specific component wasn't provided.", + isOptional: true, + }, + { + filePath: 'src/surfaces/customer-account/api/shared.ts', + syntaxKind: 'PropertySignature', + name: 'addressCode', + value: 'string | null', + description: + 'A country-specific address code, such as a short code or postal ' + + "delivery code. The value is `null` when the order address doesn't " + + 'have an address code.', + isOptional: true, + examples: [ + { + title: 'Example', + description: '', + tabs: [{code: "'01001-000'", title: 'Example'}], + }, + ], + }, +]; + +const customerAccountMailingAddressValue = ` /** + * Structured address components for countries and regions that collect them. + * The value is \`undefined\` when structured address data isn't available for + * the order address. Individual fields are \`null\` when Shopify has a + * structured address record but a specific component wasn't provided. + */ + extendedFields?: AddressExtendedFields; + + /** + * A country-specific address code, such as a short code or postal delivery + * code. The value is \`null\` when the order address doesn't have an address + * code. + * + * @example '01001-000' + */ + addressCode?: string | null; + +`; + +const addCustomerAccountMailingAddressDocs = async (generatedDocsV2Path) => { + const content = await fs.readFile(generatedDocsV2Path, 'utf8'); + const generatedDocs = JSON.parse(content); + const mailingAddressDocs = generatedDocs.MailingAddress; + + if (!mailingAddressDocs) return; + + const [sourcePath] = Object.keys(mailingAddressDocs); + const docs = mailingAddressDocs[sourcePath]; + + if (!docs?.members || !docs?.value) return; + + const existingMemberNames = new Set( + docs.members.map((member) => member.name), + ); + + const missingFields = customerAccountMailingAddressFields.filter( + (field) => !existingMemberNames.has(field.name), + ); + + if (missingFields.length > 0) { + const address2Index = docs.members.findIndex( + (member) => member.name === 'address2', + ); + const insertIndex = + address2Index === -1 ? docs.members.length : address2Index + 1; + docs.members.splice(insertIndex, 0, ...missingFields); + } + + if (!docs.value.includes('extendedFields?: AddressExtendedFields;')) { + docs.value = docs.value.replace( + ' /**\n * The city, town, or village of the address.', + `${customerAccountMailingAddressValue} /**\n * The city, town, or village of the address.`, + ); + } + + await fs.writeFile( + generatedDocsV2Path, + `${JSON.stringify(generatedDocs, null, 2)}\n`, + ); +}; + const generateExtensionsDocs = async () => { console.log( `Building Customer Account UI Extensions docs for ${EXTENSIONS_API_VERSION} version`, @@ -98,12 +192,16 @@ const generateExtensionsDocs = async () => { replaceValue: '', }); + const generatedDocsV2Path = path.join(outputDir, generatedDocsDataV2File); + // Replace 'unstable' with the exact API version in relative doc links await replaceFileContent({ - filePaths: path.join(outputDir, generatedDocsDataV2File), + filePaths: generatedDocsV2Path, searchValue: '/docs/api//unstable/', replaceValue: `/docs/api/customer-account-ui-extensions/${EXTENSIONS_API_VERSION}`, }); + + await addCustomerAccountMailingAddressDocs(generatedDocsV2Path); }; let checkoutTempFiles = []; @@ -126,10 +224,16 @@ try { // Generate targets.json console.log('Generating targets.json...'); try { - execSync(`node ${path.join(docsPath, 'build-docs-targets-json.mjs')} ${EXTENSIONS_API_VERSION}`, { - stdio: 'inherit', - cwd: rootPath, - }); + execSync( + `node ${path.join( + docsPath, + 'build-docs-targets-json.mjs', + )} ${EXTENSIONS_API_VERSION}`, + { + stdio: 'inherit', + cwd: rootPath, + }, + ); console.log('✅ Generated targets.json'); } catch (targetsError) { console.warn( diff --git a/packages/ui-extensions/docs/surfaces/customer-account/generated/customer_account_ui_extensions/2026-07-rc/generated_docs_data_v2.json b/packages/ui-extensions/docs/surfaces/customer-account/generated/customer_account_ui_extensions/2026-07-rc/generated_docs_data_v2.json index 7250f78b3d..f6f5f5432b 100644 --- a/packages/ui-extensions/docs/surfaces/customer-account/generated/customer_account_ui_extensions/2026-07-rc/generated_docs_data_v2.json +++ b/packages/ui-extensions/docs/surfaces/customer-account/generated/customer_account_ui_extensions/2026-07-rc/generated_docs_data_v2.json @@ -171,6 +171,34 @@ } ] }, + { + "filePath": "src/surfaces/customer-account/api/shared.ts", + "syntaxKind": "PropertySignature", + "name": "extendedFields", + "value": "AddressExtendedFields", + "description": "Structured address components for countries and regions that collect them. The value is `undefined` when structured address data isn't available for the order address. Individual fields are `null` when Shopify has a structured address record but a specific component wasn't provided.", + "isOptional": true + }, + { + "filePath": "src/surfaces/customer-account/api/shared.ts", + "syntaxKind": "PropertySignature", + "name": "addressCode", + "value": "string | null", + "description": "A country-specific address code, such as a short code or postal delivery code. The value is `null` when the order address doesn't have an address code.", + "isOptional": true, + "examples": [ + { + "title": "Example", + "description": "", + "tabs": [ + { + "code": "'01001-000'", + "title": "Example" + } + ] + } + ] + }, { "filePath": "src/surfaces/checkout/api/shared.ts", "syntaxKind": "PropertySignature", @@ -352,7 +380,7 @@ ] } ], - "value": "export interface MailingAddress {\n /**\n * The buyer's full name, typically a combination of first and last name.\n * The value is `undefined` if the buyer didn't provide a name.\n *\n * {% include /apps/checkout/privacy-icon.md %} Requires level 2 access to [protected customer data](/docs/apps/store/data-protection/protected-customer-data).\n *\n * @example 'John Doe'\n */\n name?: string;\n\n /**\n * The buyer's first name. Use this alongside `lastName` when you need to\n * display or process name parts separately. The value is `undefined` if\n * the buyer didn't provide a first name or the store doesn't collect\n * split names.\n *\n * {% include /apps/checkout/privacy-icon.md %} Requires level 2 access to [protected customer data](/docs/apps/store/data-protection/protected-customer-data).\n *\n * @example 'John'\n */\n firstName?: string;\n\n /**\n * The buyer's last name. Use this alongside `firstName` when you need to\n * display or process name parts separately. The value is `undefined` if\n * the buyer didn't provide a last name or the store doesn't collect\n * split names.\n *\n * {% include /apps/checkout/privacy-icon.md %} Requires level 2 access to [protected customer data](/docs/apps/store/data-protection/protected-customer-data).\n *\n * @example 'Doe'\n */\n lastName?: string;\n\n /**\n * The buyer's company name. The value is `undefined` if the buyer didn't\n * enter a company or the store doesn't collect company names.\n *\n * {% include /apps/checkout/privacy-icon.md %} Requires level 1 access to [protected customer data](/docs/apps/store/data-protection/protected-customer-data).\n *\n * @example 'Shopify'\n */\n company?: string;\n\n /**\n * The first line of the street address, including the street number and\n * name. The value is `undefined` if the buyer hasn't entered an address yet.\n *\n * {% include /apps/checkout/privacy-icon.md %} Requires level 2 access to [protected customer data](/docs/apps/store/data-protection/protected-customer-data).\n *\n * @example '151 O'Connor Street'\n */\n address1?: string;\n\n /**\n * The second line of the buyer's address, such as apartment number, suite,\n * or unit. The value is `undefined` if the buyer didn't provide a second\n * address line.\n *\n * {% include /apps/checkout/privacy-icon.md %} Requires level 2 access to [protected customer data](/docs/apps/store/data-protection/protected-customer-data).\n *\n * @example 'Ground floor'\n */\n address2?: string;\n\n /**\n * The city, town, or village of the address. The value is `undefined` if\n * the buyer hasn't entered a city yet.\n *\n * {% include /apps/checkout/privacy-icon.md %} Requires level 2 access to [protected customer data](/docs/apps/store/data-protection/protected-customer-data).\n *\n * @example 'Ottawa'\n */\n city?: string;\n\n /**\n * The postal code or ZIP code of the address, used for mail sorting and\n * delivery routing. The value is `undefined` if the buyer hasn't entered\n * one yet or the country doesn't use postal codes.\n *\n * {% include /apps/checkout/privacy-icon.md %} Requires level 2 access to [protected customer data](/docs/apps/store/data-protection/protected-customer-data).\n *\n * @example 'K2P 2L8'\n */\n zip?: string;\n\n /**\n * The two-letter country code in [ISO 3166 Alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2)\n * format. The value is `undefined` if the buyer hasn't selected a country\n * yet.\n *\n * {% include /apps/checkout/privacy-icon.md %} Requires level 2 access to [protected customer data](/docs/apps/store/data-protection/protected-customer-data).\n *\n * @example 'CA' for Canada.\n */\n countryCode?: CountryCode;\n\n /**\n * The province, state, prefecture, or region code of the address. The\n * format varies by country. The value is `undefined` if the buyer hasn't\n * selected one yet or the country doesn't have provinces.\n *\n * {% include /apps/checkout/privacy-icon.md %} Requires level 2 access to [protected customer data](/docs/apps/store/data-protection/protected-customer-data).\n *\n * @example 'ON' for Ontario.\n */\n provinceCode?: string;\n\n /**\n * The phone number associated with the address, typically in international\n * format. The value is `undefined` if the buyer didn't provide a phone\n * number or the store doesn't collect phone numbers.\n *\n * {% include /apps/checkout/privacy-icon.md %} Requires level 2 access to [protected customer data](/docs/apps/store/data-protection/protected-customer-data).\n *\n * @example '+1 613 111 2222'\n */\n phone?: string;\n}" + "value": "export interface MailingAddress {\n /**\n * The buyer's full name, typically a combination of first and last name.\n * The value is `undefined` if the buyer didn't provide a name.\n *\n * {% include /apps/checkout/privacy-icon.md %} Requires level 2 access to [protected customer data](/docs/apps/store/data-protection/protected-customer-data).\n *\n * @example 'John Doe'\n */\n name?: string;\n\n /**\n * The buyer's first name. Use this alongside `lastName` when you need to\n * display or process name parts separately. The value is `undefined` if\n * the buyer didn't provide a first name or the store doesn't collect\n * split names.\n *\n * {% include /apps/checkout/privacy-icon.md %} Requires level 2 access to [protected customer data](/docs/apps/store/data-protection/protected-customer-data).\n *\n * @example 'John'\n */\n firstName?: string;\n\n /**\n * The buyer's last name. Use this alongside `firstName` when you need to\n * display or process name parts separately. The value is `undefined` if\n * the buyer didn't provide a last name or the store doesn't collect\n * split names.\n *\n * {% include /apps/checkout/privacy-icon.md %} Requires level 2 access to [protected customer data](/docs/apps/store/data-protection/protected-customer-data).\n *\n * @example 'Doe'\n */\n lastName?: string;\n\n /**\n * The buyer's company name. The value is `undefined` if the buyer didn't\n * enter a company or the store doesn't collect company names.\n *\n * {% include /apps/checkout/privacy-icon.md %} Requires level 1 access to [protected customer data](/docs/apps/store/data-protection/protected-customer-data).\n *\n * @example 'Shopify'\n */\n company?: string;\n\n /**\n * The first line of the street address, including the street number and\n * name. The value is `undefined` if the buyer hasn't entered an address yet.\n *\n * {% include /apps/checkout/privacy-icon.md %} Requires level 2 access to [protected customer data](/docs/apps/store/data-protection/protected-customer-data).\n *\n * @example '151 O'Connor Street'\n */\n address1?: string;\n\n /**\n * The second line of the buyer's address, such as apartment number, suite,\n * or unit. The value is `undefined` if the buyer didn't provide a second\n * address line.\n *\n * {% include /apps/checkout/privacy-icon.md %} Requires level 2 access to [protected customer data](/docs/apps/store/data-protection/protected-customer-data).\n *\n * @example 'Ground floor'\n */\n address2?: string;\n\n /**\n * Structured address components for countries and regions that collect them.\n * The value is `undefined` when structured address data isn't available for\n * the order address. Individual fields are `null` when Shopify has a\n * structured address record but a specific component wasn't provided.\n */\n extendedFields?: AddressExtendedFields;\n\n /**\n * A country-specific address code, such as a short code or postal delivery\n * code. The value is `null` when the order address doesn't have an address\n * code.\n *\n * @example '01001-000'\n */\n addressCode?: string | null;\n\n /**\n * The city, town, or village of the address. The value is `undefined` if\n * the buyer hasn't entered a city yet.\n *\n * {% include /apps/checkout/privacy-icon.md %} Requires level 2 access to [protected customer data](/docs/apps/store/data-protection/protected-customer-data).\n *\n * @example 'Ottawa'\n */\n city?: string;\n\n /**\n * The postal code or ZIP code of the address, used for mail sorting and\n * delivery routing. The value is `undefined` if the buyer hasn't entered\n * one yet or the country doesn't use postal codes.\n *\n * {% include /apps/checkout/privacy-icon.md %} Requires level 2 access to [protected customer data](/docs/apps/store/data-protection/protected-customer-data).\n *\n * @example 'K2P 2L8'\n */\n zip?: string;\n\n /**\n * The two-letter country code in [ISO 3166 Alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2)\n * format. The value is `undefined` if the buyer hasn't selected a country\n * yet.\n *\n * {% include /apps/checkout/privacy-icon.md %} Requires level 2 access to [protected customer data](/docs/apps/store/data-protection/protected-customer-data).\n *\n * @example 'CA' for Canada.\n */\n countryCode?: CountryCode;\n\n /**\n * The province, state, prefecture, or region code of the address. The\n * format varies by country. The value is `undefined` if the buyer hasn't\n * selected one yet or the country doesn't have provinces.\n *\n * {% include /apps/checkout/privacy-icon.md %} Requires level 2 access to [protected customer data](/docs/apps/store/data-protection/protected-customer-data).\n *\n * @example 'ON' for Ontario.\n */\n provinceCode?: string;\n\n /**\n * The phone number associated with the address, typically in international\n * format. The value is `undefined` if the buyer didn't provide a phone\n * number or the store doesn't collect phone numbers.\n *\n * {% include /apps/checkout/privacy-icon.md %} Requires level 2 access to [protected customer data](/docs/apps/store/data-protection/protected-customer-data).\n *\n * @example '+1 613 111 2222'\n */\n phone?: string;\n}" } }, "CountryCode": { @@ -8535,6 +8563,117 @@ "isPublicDocs": true } }, + "AddressExtendedFields": { + "src/surfaces/customer-account/api/shared.ts": { + "filePath": "src/surfaces/customer-account/api/shared.ts", + "name": "AddressExtendedFields", + "description": "Structured extended address fields for countries and regions that collect address components separately from the flat address lines. These fields are available on order shipping and billing addresses when the order was placed with structured address data.", + "isPublicDocs": true, + "members": [ + { + "filePath": "src/surfaces/customer-account/api/shared.ts", + "syntaxKind": "PropertySignature", + "name": "district", + "value": "string | null", + "description": "The district or neighborhood.", + "isOptional": true, + "examples": [ + { + "title": "Example", + "description": "", + "tabs": [ + { + "code": "'Bela Vista'", + "title": "Example" + } + ] + } + ] + }, + { + "filePath": "src/surfaces/customer-account/api/shared.ts", + "syntaxKind": "PropertySignature", + "name": "line2", + "value": "string | null", + "description": "Additional address information, such as a block, floor, or unit.", + "isOptional": true, + "examples": [ + { + "title": "Example", + "description": "", + "tabs": [ + { + "code": "'10th floor'", + "title": "Example" + } + ] + } + ] + }, + { + "filePath": "src/surfaces/customer-account/api/shared.ts", + "syntaxKind": "PropertySignature", + "name": "streetName", + "value": "string | null", + "description": "The street name without the building or street number.", + "isOptional": true, + "examples": [ + { + "title": "Example", + "description": "", + "tabs": [ + { + "code": "'Avenida Paulista'", + "title": "Example" + } + ] + } + ] + }, + { + "filePath": "src/surfaces/customer-account/api/shared.ts", + "syntaxKind": "PropertySignature", + "name": "streetNumber", + "value": "string | null", + "description": "The building or street number.", + "isOptional": true, + "examples": [ + { + "title": "Example", + "description": "", + "tabs": [ + { + "code": "'123'", + "title": "Example" + } + ] + } + ] + }, + { + "filePath": "src/surfaces/customer-account/api/shared.ts", + "syntaxKind": "PropertySignature", + "name": "subdistrict", + "value": "string | null", + "description": "The subdistrict or smaller locality.", + "isOptional": true, + "examples": [ + { + "title": "Example", + "description": "", + "tabs": [ + { + "code": "'Centro'", + "title": "Example" + } + ] + } + ] + } + ], + "value": "export interface AddressExtendedFields {\n /**\n * The street name without the building or street number.\n *\n * @example 'Avenida Paulista'\n */\n streetName?: string | null;\n\n /**\n * The building or street number.\n *\n * @example '123'\n */\n streetNumber?: string | null;\n\n /**\n * Additional address information, such as a block, floor, or unit.\n *\n * @example '10th floor'\n */\n line2?: string | null;\n\n /**\n * The district or neighborhood.\n *\n * @example 'Bela Vista'\n */\n district?: string | null;\n\n /**\n * The subdistrict or smaller locality.\n *\n * @example 'Centro'\n */\n subdistrict?: string | null;\n}" + } + }, "AuthenticatedAccount": { "src/surfaces/customer-account/api/shared.ts": { "filePath": "src/surfaces/customer-account/api/shared.ts", @@ -8923,7 +9062,7 @@ "syntaxKind": "PropertySignature", "name": "billingAddress", "value": "SubscribableSignalLike", - "description": "The billing address associated with the buyer's payment method for the order. The value is `undefined` if the order doesn't have a billing address on file.\n\nReflects the state at the time the order was placed. Doesn't update if the customer changes their account address afterward.", + "description": "The billing address associated with the buyer's payment method for the order. The value is `undefined` if the order doesn't have a billing address on file.\n\nIncludes structured address fields, such as `addressCode` and `extendedFields`, when they're available for the order address. Reflects the state at the time the order was placed. Doesn't update if the customer changes their account address afterward.", "isOptional": true }, { @@ -9036,7 +9175,7 @@ "syntaxKind": "PropertySignature", "name": "shippingAddress", "value": "SubscribableSignalLike", - "description": "The shipping address that the buyer provided for the order. This is where physical goods are delivered. The value is `undefined` if the order contains only digital products or if a shipping address wasn't required.\n\nReflects the state at the time the order was placed. Doesn't update if the customer changes their account address afterward.", + "description": "The shipping address that the buyer provided for the order. This is where physical goods are delivered. The value is `undefined` if the order contains only digital products or if a shipping address wasn't required.\n\nIncludes structured address fields, such as `addressCode` and `extendedFields`, when they're available for the order address. Reflects the state at the time the order was placed. Doesn't update if the customer changes their account address afterward.", "isOptional": true }, { @@ -9066,7 +9205,7 @@ ] } ], - "value": "export interface OrderStatusApi {\n /**\n * The gift cards that were applied to the order. Each gift card includes the last four\n * characters of the code, the amount used for this order, and the remaining balance.\n */\n appliedGiftCards: SubscribableSignalLike;\n\n /**\n * The [metafields](/docs/apps/build/custom-data/metafields) requested in the\n * [`shopify.extension.toml`](/docs/apps/build/customer-accounts/metafields#create-the-metafield-definition)\n * file. Metafields are custom data fields that store additional information on Shopify resources\n * such as products, variants, customers, and the shop. These metafields are updated when there's\n * a change in the merchandise items being purchased by the customer.\n *\n * App owned metafields are supported and are returned using the `$app` format. The fully qualified reserved namespace format such as `app--{your-app-id}[--{optional-namespace}]` is not supported. See [app owned metafields](/docs/apps/build/metafields#app-owned-metafields) for more information.\n *\n * {% include /apps/checkout/privacy-icon.md %} Requires level 1 access to [protected customer data](/docs/apps/store/data-protection/protected-customer-data) when accessing metafields attached to `customer`, `company`, or `companyLocation` resources.\n */\n appMetafields: SubscribableSignalLike;\n\n /**\n * The custom key-value pairs attached to the order by the customer or by other extensions\n * during cart or checkout. These are commonly used for delivery instructions, gift messages,\n * or other information the buyer provides. The value is `undefined` if no attributes were set.\n */\n attributes: SubscribableSignalLike;\n\n /**\n * The buyer who placed the order, including their customer account, email, phone number, and B2B purchasing company. Use this to personalize the **Order status** page or identify B2B orders.\n *\n * Reflects the customer account at the time the order was placed. Doesn't\n * update if account details change afterward.\n */\n buyerIdentity?: OrderStatusBuyerIdentity;\n\n /**\n * The checkout settings that were active when the buyer placed the order, such as\n * whether order notes and login are enabled.\n *\n * Returns the merchant's checkout configuration at the time of checkout.\n * Doesn't reflect updates made after the order was placed.\n */\n checkoutSettings: SubscribableSignalLike;\n\n /**\n * A breakdown of the costs for the order, including the subtotal, shipping, tax, and total amounts.\n */\n cost: CartCost;\n\n /**\n * A list of discount codes that the buyer entered during checkout and that were applied to the order.\n */\n discountCodes: SubscribableSignalLike;\n\n /**\n * The cart-level discount allocations applied to the order. A discount allocation represents\n * how a discount is distributed across the order. Each allocation includes the discounted\n * amount and one of the following types:\n *\n * - `CartCodeDiscountAllocation`: A discount the buyer applied by entering a code at checkout.\n * - `CartAutomaticDiscountAllocation`: A discount the merchant configured in Shopify admin to apply automatically.\n * - `CartCustomDiscountAllocation`: A discount created programmatically by a [Shopify Function](/docs/apps/build/functions).\n *\n * Returns order-level discounts only. For per-line discount allocations,\n * read from individual cart lines via the Cart Lines API.\n */\n discountAllocations: SubscribableSignalLike;\n\n /**\n * Metadata about the current extension, including its target, API version, and capabilities.\n */\n extension: Extension;\n\n /**\n * The identifier that specifies where in Shopify's UI your code is being injected. This will be one of the targets you have included in your extension's configuration file.\n *\n * @example 'customer-account.order-status.block.render'\n * Learn more about [targets](/docs/api/customer-account-ui-extensions/{API_VERSION}/targets) and [target configuration](/docs/api/customer-account-ui-extensions/{API_VERSION}#configuration).\n *\n * @deprecated Use `extension.target` instead.\n */\n extensionPoint: Target;\n\n /**\n * A list of line items in the order. Each line includes the merchandise, quantity, cost,\n * custom attributes, and discount allocations.\n */\n lines: SubscribableSignalLike;\n\n /**\n * The buyer's locale, currency, time zone, country, and market context for the order.\n * Use these values to adapt your extension's content to the buyer's region. For formatted\n * dates, numbers, and translated strings, use the [Localization API](/docs/api/customer-account-ui-extensions/{API_VERSION}/target-apis/platform-apis/localization-api)\n * instead.\n */\n localization: OrderStatusLocalization;\n\n /**\n * A note left by the customer to the merchant, either in their cart or during checkout.\n * The value is `undefined` if no note was provided.\n */\n note: SubscribableSignalLike;\n\n /**\n * The order that was placed after checkout completion. Includes the order ID,\n * display name, confirmation number, and timestamps for processing and cancellation.\n * The value is `undefined` if the order hasn't been fully processed yet.\n */\n order: SubscribableSignalLike;\n\n /**\n * The token that identifies the checkout session used to create the order. Use this value\n * to correlate the order with analytics events or backend API calls. This matches the\n * `token` field in the [WebPixel checkout payload](/docs/api/pixels/customer-events#checkout).\n * The value is `undefined` if the checkout token is unavailable.\n */\n checkoutToken: SubscribableSignalLike;\n\n /**\n * The shipping address that the buyer provided for the order. This is where physical goods\n * are delivered. The value is `undefined` if the order contains only digital products or\n * if a shipping address wasn't required.\n *\n * Reflects the state at the time the order was placed. Doesn't update if the\n * customer changes their account address afterward.\n */\n shippingAddress?: SubscribableSignalLike;\n\n /**\n * The billing address associated with the buyer's payment method for the order. The value\n * is `undefined` if the order doesn't have a billing address on file.\n *\n * Reflects the state at the time the order was placed. Doesn't update if the\n * customer changes their account address afterward.\n */\n billingAddress?: SubscribableSignalLike;\n\n /**\n * The shop where the order was placed. Includes the shop ID, name, primary\n * storefront URL, and myshopify.com domain.\n */\n shop: Shop;\n\n /**\n * The API version that the extension is using, such as `'2026-01'` or `'unstable'`. This corresponds to the version declared in your extension's configuration.\n *\n * @example 'unstable'\n */\n version: Version;\n\n /**\n * Triggers a login prompt if the customer is viewing a pre-authenticated **Order status** page.\n * Use this to require full authentication before displaying sensitive information in your extension.\n *\n * Triggers a login prompt for pre-authenticated buyers. Doesn't guarantee\n * the buyer completes the login. Handle the dismissal case in your code.\n */\n requireLogin: () => Promise;\n\n /**\n * The buyer's current authentication level on the **Order status** page. Use this to determine whether to display sensitive information or prompt the buyer to log in.\n *\n * Read-only. The authentication level can't be changed programmatically.\n */\n authenticationState: SubscribableSignalLike;\n}" + "value": "export interface OrderStatusApi {\n /**\n * The gift cards that were applied to the order. Each gift card includes the last four\n * characters of the code, the amount used for this order, and the remaining balance.\n */\n appliedGiftCards: SubscribableSignalLike;\n\n /**\n * The [metafields](/docs/apps/build/custom-data/metafields) requested in the\n * [`shopify.extension.toml`](/docs/apps/build/customer-accounts/metafields#create-the-metafield-definition)\n * file. Metafields are custom data fields that store additional information on Shopify resources\n * such as products, variants, customers, and the shop. These metafields are updated when there's\n * a change in the merchandise items being purchased by the customer.\n *\n * App owned metafields are supported and are returned using the `$app` format. The fully qualified reserved namespace format such as `app--{your-app-id}[--{optional-namespace}]` is not supported. See [app owned metafields](/docs/apps/build/metafields#app-owned-metafields) for more information.\n *\n * {% include /apps/checkout/privacy-icon.md %} Requires level 1 access to [protected customer data](/docs/apps/store/data-protection/protected-customer-data) when accessing metafields attached to `customer`, `company`, or `companyLocation` resources.\n */\n appMetafields: SubscribableSignalLike;\n\n /**\n * The custom key-value pairs attached to the order by the customer or by other extensions\n * during cart or checkout. These are commonly used for delivery instructions, gift messages,\n * or other information the buyer provides. The value is `undefined` if no attributes were set.\n */\n attributes: SubscribableSignalLike;\n\n /**\n * The buyer who placed the order, including their customer account, email, phone number, and B2B purchasing company. Use this to personalize the **Order status** page or identify B2B orders.\n *\n * Reflects the customer account at the time the order was placed. Doesn't\n * update if account details change afterward.\n */\n buyerIdentity?: OrderStatusBuyerIdentity;\n\n /**\n * The checkout settings that were active when the buyer placed the order, such as\n * whether order notes and login are enabled.\n *\n * Returns the merchant's checkout configuration at the time of checkout.\n * Doesn't reflect updates made after the order was placed.\n */\n checkoutSettings: SubscribableSignalLike;\n\n /**\n * A breakdown of the costs for the order, including the subtotal, shipping, tax, and total amounts.\n */\n cost: CartCost;\n\n /**\n * A list of discount codes that the buyer entered during checkout and that were applied to the order.\n */\n discountCodes: SubscribableSignalLike;\n\n /**\n * The cart-level discount allocations applied to the order. A discount allocation represents\n * how a discount is distributed across the order. Each allocation includes the discounted\n * amount and one of the following types:\n *\n * - `CartCodeDiscountAllocation`: A discount the buyer applied by entering a code at checkout.\n * - `CartAutomaticDiscountAllocation`: A discount the merchant configured in Shopify admin to apply automatically.\n * - `CartCustomDiscountAllocation`: A discount created programmatically by a [Shopify Function](/docs/apps/build/functions).\n *\n * Returns order-level discounts only. For per-line discount allocations,\n * read from individual cart lines via the Cart Lines API.\n */\n discountAllocations: SubscribableSignalLike;\n\n /**\n * Metadata about the current extension, including its target, API version, and capabilities.\n */\n extension: Extension;\n\n /**\n * The identifier that specifies where in Shopify's UI your code is being injected. This will be one of the targets you have included in your extension's configuration file.\n *\n * @example 'customer-account.order-status.block.render'\n * Learn more about [targets](/docs/api/customer-account-ui-extensions/{API_VERSION}/targets) and [target configuration](/docs/api/customer-account-ui-extensions/{API_VERSION}#configuration).\n *\n * @deprecated Use `extension.target` instead.\n */\n extensionPoint: Target;\n\n /**\n * A list of line items in the order. Each line includes the merchandise, quantity, cost,\n * custom attributes, and discount allocations.\n */\n lines: SubscribableSignalLike;\n\n /**\n * The buyer's locale, currency, time zone, country, and market context for the order.\n * Use these values to adapt your extension's content to the buyer's region. For formatted\n * dates, numbers, and translated strings, use the [Localization API](/docs/api/customer-account-ui-extensions/{API_VERSION}/target-apis/platform-apis/localization-api)\n * instead.\n */\n localization: OrderStatusLocalization;\n\n /**\n * A note left by the customer to the merchant, either in their cart or during checkout.\n * The value is `undefined` if no note was provided.\n */\n note: SubscribableSignalLike;\n\n /**\n * The order that was placed after checkout completion. Includes the order ID,\n * display name, confirmation number, and timestamps for processing and cancellation.\n * The value is `undefined` if the order hasn't been fully processed yet.\n */\n order: SubscribableSignalLike;\n\n /**\n * The token that identifies the checkout session used to create the order. Use this value\n * to correlate the order with analytics events or backend API calls. This matches the\n * `token` field in the [WebPixel checkout payload](/docs/api/pixels/customer-events#checkout).\n * The value is `undefined` if the checkout token is unavailable.\n */\n checkoutToken: SubscribableSignalLike;\n\n /**\n * The shipping address that the buyer provided for the order. This is where physical goods\n * are delivered. The value is `undefined` if the order contains only digital products or\n * if a shipping address wasn't required.\n *\n * Includes structured address fields, such as `addressCode` and `extendedFields`,\n * when they're available for the order address. Reflects the state at the time\n * the order was placed. Doesn't update if the customer changes their account\n * address afterward.\n */\n shippingAddress?: SubscribableSignalLike;\n\n /**\n * The billing address associated with the buyer's payment method for the order. The value\n * is `undefined` if the order doesn't have a billing address on file.\n *\n * Includes structured address fields, such as `addressCode` and `extendedFields`,\n * when they're available for the order address. Reflects the state at the time\n * the order was placed. Doesn't update if the customer changes their account\n * address afterward.\n */\n billingAddress?: SubscribableSignalLike;\n\n /**\n * The shop where the order was placed. Includes the shop ID, name, primary\n * storefront URL, and myshopify.com domain.\n */\n shop: Shop;\n\n /**\n * The API version that the extension is using, such as `'2026-01'` or `'unstable'`. This corresponds to the version declared in your extension's configuration.\n *\n * @example 'unstable'\n */\n version: Version;\n\n /**\n * Triggers a login prompt if the customer is viewing a pre-authenticated **Order status** page.\n * Use this to require full authentication before displaying sensitive information in your extension.\n *\n * Triggers a login prompt for pre-authenticated buyers. Doesn't guarantee\n * the buyer completes the login. Handle the dismissal case in your code.\n */\n requireLogin: () => Promise;\n\n /**\n * The buyer's current authentication level on the **Order status** page. Use this to determine whether to display sensitive information or prompt the buyer to log in.\n *\n * Read-only. The authentication level can't be changed programmatically.\n */\n authenticationState: SubscribableSignalLike;\n}" } }, "OrderStatusBuyerIdentity": { @@ -26257,7 +26396,7 @@ "syntaxKind": "PropertySignature", "name": "billingAddress", "value": "SubscribableSignalLike", - "description": "The billing address associated with the buyer's payment method for the order. The value is `undefined` if the order doesn't have a billing address on file.\n\nReflects the state at the time the order was placed. Doesn't update if the customer changes their account address afterward.", + "description": "The billing address associated with the buyer's payment method for the order. The value is `undefined` if the order doesn't have a billing address on file.\n\nIncludes structured address fields, such as `addressCode` and `extendedFields`, when they're available for the order address. Reflects the state at the time the order was placed. Doesn't update if the customer changes their account address afterward.", "isOptional": true }, { @@ -26265,7 +26404,7 @@ "syntaxKind": "PropertySignature", "name": "shippingAddress", "value": "SubscribableSignalLike", - "description": "The shipping address that the buyer provided for the order. This is where physical goods are delivered. The value is `undefined` if the order contains only digital products or if a shipping address wasn't required.\n\nReflects the state at the time the order was placed. Doesn't update if the customer changes their account address afterward.", + "description": "The shipping address that the buyer provided for the order. This is where physical goods are delivered. The value is `undefined` if the order contains only digital products or if a shipping address wasn't required.\n\nIncludes structured address fields, such as `addressCode` and `extendedFields`, when they're available for the order address. Reflects the state at the time the order was placed. Doesn't update if the customer changes their account address afterward.", "isOptional": true } ], @@ -182672,4 +182811,4 @@ "value": "export interface UrlFieldProps extends URLFieldElementProps, UrlFieldEvents {\n}" } } -} \ No newline at end of file +} diff --git a/packages/ui-extensions/src/surfaces/customer-account/api.ts b/packages/ui-extensions/src/surfaces/customer-account/api.ts index 194c3c1cee..d95f0dd13b 100644 --- a/packages/ui-extensions/src/surfaces/customer-account/api.ts +++ b/packages/ui-extensions/src/surfaces/customer-account/api.ts @@ -51,6 +51,7 @@ export type { GraphQLError, SellingPlan, StorefrontApiVersion, + AddressExtendedFields, MailingAddress, ApiVersion, Capability, diff --git a/packages/ui-extensions/src/surfaces/customer-account/api/order-status/order-status.ts b/packages/ui-extensions/src/surfaces/customer-account/api/order-status/order-status.ts index fbc1e6028f..8bc3bdd1af 100644 --- a/packages/ui-extensions/src/surfaces/customer-account/api/order-status/order-status.ts +++ b/packages/ui-extensions/src/surfaces/customer-account/api/order-status/order-status.ts @@ -341,8 +341,10 @@ export interface OrderStatusApi { * are delivered. The value is `undefined` if the order contains only digital products or * if a shipping address wasn't required. * - * Reflects the state at the time the order was placed. Doesn't update if the - * customer changes their account address afterward. + * Includes structured address fields, such as `addressCode` and `extendedFields`, + * when they're available for the order address. Reflects the state at the time + * the order was placed. Doesn't update if the customer changes their account + * address afterward. */ shippingAddress?: SubscribableSignalLike; @@ -350,8 +352,10 @@ export interface OrderStatusApi { * The billing address associated with the buyer's payment method for the order. The value * is `undefined` if the order doesn't have a billing address on file. * - * Reflects the state at the time the order was placed. Doesn't update if the - * customer changes their account address afterward. + * Includes structured address fields, such as `addressCode` and `extendedFields`, + * when they're available for the order address. Reflects the state at the time + * the order was placed. Doesn't update if the customer changes their account + * address afterward. */ billingAddress?: SubscribableSignalLike; diff --git a/packages/ui-extensions/src/surfaces/customer-account/api/shared.ts b/packages/ui-extensions/src/surfaces/customer-account/api/shared.ts index 0299d141a9..07f7928545 100644 --- a/packages/ui-extensions/src/surfaces/customer-account/api/shared.ts +++ b/packages/ui-extensions/src/surfaces/customer-account/api/shared.ts @@ -250,6 +250,51 @@ export interface Attribute { value: string; } +/** + * Structured extended address fields for countries and regions that collect + * address components separately from the flat address lines. These fields are + * available on order shipping and billing addresses when the order was placed + * with structured address data. + * + * @publicDocs + */ +export interface AddressExtendedFields { + /** + * The street name without the building or street number. + * + * @example 'Avenida Paulista' + */ + streetName?: string | null; + + /** + * The building or street number. + * + * @example '123' + */ + streetNumber?: string | null; + + /** + * Additional address information, such as a block, floor, or unit. + * + * @example '10th floor' + */ + line2?: string | null; + + /** + * The district or neighborhood. + * + * @example 'Bela Vista' + */ + district?: string | null; + + /** + * The subdistrict or smaller locality. + * + * @example 'Centro' + */ + subdistrict?: string | null; +} + /** * A mailing address associated with the order, such as a shipping or billing address. * @@ -300,6 +345,23 @@ export interface MailingAddress { */ address2?: string; + /** + * Structured address components for countries and regions that collect them. + * The value is `undefined` when structured address data isn't available for + * the order address. Individual fields are `null` when Shopify has a + * structured address record but a specific component wasn't provided. + */ + extendedFields?: AddressExtendedFields; + + /** + * A country-specific address code, such as a short code or postal delivery + * code. The value is `null` when the order address doesn't have an address + * code. + * + * @example '01001-000' + */ + addressCode?: string | null; + /** * The city, town, or village of the address. *