diff --git a/src/data/navigation/sections/rest.js b/src/data/navigation/sections/rest.js index 9353c3fff..26db5b3bb 100644 --- a/src/data/navigation/sections/rest.js +++ b/src/data/navigation/sections/rest.js @@ -459,6 +459,10 @@ module.exports = [ title: "Step 4. Delete an image of a product", path: "/rest/tutorials/image/delete.md", }, + { + title: "Manage product images at the store view level", + path: "/rest/tutorials/image/product-image-store-scope.md", + }, ], }, ], diff --git a/src/pages/graphql/payment-methods/payflow-pro-vault.md b/src/pages/graphql/payment-methods/payflow-pro-vault.md index d3e25be57..65d49e00d 100644 --- a/src/pages/graphql/payment-methods/payflow-pro-vault.md +++ b/src/pages/graphql/payment-methods/payflow-pro-vault.md @@ -18,6 +18,8 @@ The following conditions must be true to use this payment method: You cannot use this payment method if the customer decides to use a credit or debit card that is not stored in the vault. +PayPal PayFlow Pro transaction IDs (PNREFs) are valid for use in Reference Transactions for a fixed period of 12 months. Once expired, the saved card will no longer be displayed and must be added again. + If the customer's stored payment information becomes outdated, use the [deletePaymentToken mutation](../schema/checkout/mutations/delete-payment-token.md) to remove the token. Then perform the actions described in the [PayPal Payflow Pro payment method](../payment-methods/payflow-pro.md) to generate a new token and process the order. diff --git a/src/pages/graphql/schema/b2b/company/queries/company.md b/src/pages/graphql/schema/b2b/company/queries/company.md index 66cc5639b..408a0259f 100644 --- a/src/pages/graphql/schema/b2b/company/queries/company.md +++ b/src/pages/graphql/schema/b2b/company/queries/company.md @@ -115,6 +115,7 @@ query{ firstname lastname email + id } ... on CompanyTeam { name @@ -143,7 +144,8 @@ query{ "__typename": "Customer", "firstname": "Taina", "lastname": "Garofalo", - "email": "donadmin@example.com" + "email": "donadmin@example.com", + "id": "Ng==" } }, { @@ -159,7 +161,8 @@ query{ "__typename": "Customer", "firstname": "B", "lastname": "BB", - "email": "bbb@example.com" + "email": "bbb@example.com", + "id": "Nw==" } }, { @@ -175,7 +178,8 @@ query{ "__typename": "Customer", "firstname": "A", "lastname": "AA", - "email": "aa@example.com" + "email": "aa@example.com", + "id": "NQ==" } }, { @@ -191,7 +195,8 @@ query{ "__typename": "Customer", "firstname": "C", "lastname": "CC", - "email": "ccc@example.com" + "email": "ccc@example.com", + "id": "NQ==" } } ] diff --git a/src/pages/graphql/schema/cart/mutations/place-order.md b/src/pages/graphql/schema/cart/mutations/place-order.md index d23cd3e30..a23373b9b 100644 --- a/src/pages/graphql/schema/cart/mutations/place-order.md +++ b/src/pages/graphql/schema/cart/mutations/place-order.md @@ -16,6 +16,8 @@ Perform the following actions before using the `placeOrder` mutation: - Set the payment method - For guest customers, assign an email to the cart +As of Commerce 2.4.9, the `PlaceOrderOutput` object contains the errors available on the top of the response node. This assures easy error control and provides compatibility with older versions. + As of Commerce 2.4.7, the `PlaceOrderOutput` object can contain `orderV2`, which provides full details about the order. When the mutation runs, Commerce generates and returns a token in the `orderV2.token` field. You can supply the token value to the [`guestOrderByToken` query](../../orders/queries/guest-order-by-token.md) to retrieve details about an order created by a guest shopper. @@ -53,10 +55,6 @@ mutation { number token } - errors { - message - code - } } } ``` @@ -70,8 +68,7 @@ mutation { "orderV2": { "number": "000000006", "token": "0:3:OSScWU6PKLn3kFyMhNWyskG0opgVvFBnJmtuaFHKGwDFT83S6Kv9U39iYwixuU+vhwDz2AF4pCs3GtLhHbQ=" - }, - "errors": [] + } } } } diff --git a/src/pages/rest/tutorials/image/index.md b/src/pages/rest/tutorials/image/index.md index f934b7694..340b15b57 100644 --- a/src/pages/rest/tutorials/image/index.md +++ b/src/pages/rest/tutorials/image/index.md @@ -19,6 +19,10 @@ This tutorial demonstrates how to use the Adobe Commerce REST APIs to: 1. [Delete an image](delete.md) + + +For multi-store environments, see [Manage product images at the store view level](product-image-store-scope.md) for how `media_gallery_entries` behaves across store views and how to restore inherited field values. + This **4-step tutorial** generally takes **30 minutes**. ## Before you begin diff --git a/src/pages/rest/tutorials/image/product-image-store-scope.md b/src/pages/rest/tutorials/image/product-image-store-scope.md new file mode 100644 index 000000000..ff2a131b8 --- /dev/null +++ b/src/pages/rest/tutorials/image/product-image-store-scope.md @@ -0,0 +1,425 @@ +--- +title: Manage product images at the store view level +description: Learn how to use the Adobe Commerce REST API to preserve, override, and restore product image gallery settings per store view in a multi-store setup. +keywords: + - REST +--- + +# Manage product images at the store view level + +This topic explains how product image gallery inheritance works in a multi-store Adobe Commerce setup and how to control it using the REST API. These behaviours only apply when your installation has multiple store views. In a single-store setup, all requests target the global scope and inheritance does not apply. + +If you are new to the product media API, complete the [Add and manage product images tutorial](/rest/tutorials/image/) first. + +## Before you begin + +* An Adobe Commerce instance with at least two store views configured. The examples use `default` and a second store view. See [Add a store view](https://experienceleague.adobe.com/docs/commerce-admin/stores-sales/site-store/store-views.html) in the Admin documentation. + +* A product with images in all store views, where images currently use the default value (the **Use Default Value** checkbox is enabled in Admin) in each store view. + +* An admin access token. See [Generate an admin token](../../../get-started/authentication/gs-authentication-token.md). + +* A REST client, such as Postman. + +## Preserve images during a product update + +When you update a product at the store view level, you can control whether the request affects the product's media gallery. + +### Omit media_gallery_entries + +If the `media_gallery_entries` field is not present in the payload, no changes are made to the product images in that scope. All store views continue to use the default value. + +**Endpoint:** + +```html +POST http://domain.com/rest/default/V1/products +``` + + + +#### Payload + +```json +{ + "product": { + "sku": "MJ03", + "name": "product name override in default store view" + } +} +``` + +#### Response + +```json +{ + "sku": "MJ03", + "name": "product name override in default store view", + "media_gallery_entries": [ + { + "id": 709, + "media_type": "image", + "label": "", + "position": 1, + "disabled": false, + "types": [ + "image", + "small_image", + "thumbnail" + ], + "file": "\/m\/j\/mj03-black_main_12.jpg" + }, + { + "id": 710, + "media_type": "image", + "label": "", + "position": 2, + "disabled": false, + "types": [], + "file": "\/m\/j\/mj03-black_alt1_12.jpg" + }, + { + "id": 711, + "media_type": "image", + "label": "", + "position": 3, + "disabled": false, + "types": [], + "file": "\/m\/j\/mj03-black_back_12.jpg" + } + ] +} +``` + +After this call, images in each store view continue to implement the **Use Default Value** setting. + +### Set media_gallery_entries to null + +Setting `media_gallery_entries` to `null` and omitting the field are equivalent. Neither modifies the images currently configured for any store view. + + + +Setting `media_gallery_entries` to an empty array `[]` is **not** the same as `null`. An empty array is treated as an explicit instruction to remove all gallery entries from all store views. Always use `null` or omit the field when you do not intend to modify images. + +**Endpoint:** + +```html +POST http://domain.com/rest/default/V1/products +``` + + + +#### Payload + +```json +{ + "product": { + "sku": "MJ03", + "name": "product name override in default store view", + "media_gallery_entries": null + } +} +``` + +#### Response + +```json +{ + "sku": "MJ03", + "name": "product name override in default store view", + "media_gallery_entries": [ + { + "id": 709, + "media_type": "image", + "label": "", + "position": 1, + "disabled": false, + "types": [ + "image", + "small_image", + "thumbnail" + ], + "file": "\/m\/j\/mj03-black_main_12.jpg" + }, + { + "id": 710, + "media_type": "image", + "label": "", + "position": 2, + "disabled": false, + "types": [], + "file": "\/m\/j\/mj03-black_alt1_12.jpg" + }, + { + "id": 711, + "media_type": "image", + "label": "", + "position": 3, + "disabled": false, + "types": [], + "file": "\/m\/j\/mj03-black_back_12.jpg" + } + ] +} +``` + +## Override store view image fields + +When you retrieve a product and POST it back with the `media_gallery_entries` array populated, the store view fields are explicitly set — overriding any inherited values. + +**Step 1.** Retrieve the full product data from the store view you want to update. + +**Endpoint:** + +```html +GET http://domain.com/rest/default/V1/products/MJ03 +``` + +**Step 2.** Use the `media_gallery_entries` from the GET response in an update call. + +**Endpoint:** + +```html +POST http://domain.com/rest/default/V1/products +``` + +After this call: + +* In the **default store view**: image sort order, label, visibility, and roles are no longer using the default value (**Use Default Value** is unchecked). + +* In the **second store view**: image fields continue to use the default value (unaffected). + +## Restore inheritance by setting fields to null + +Setting individual image fields to `null` restores the **Use Default Value** state for those fields. This is the equivalent of re-enabling the **Use Default Value** checkbox in the Admin product editor. + +The following fields support `null` to restore inheritance: + +| Field | Effect of `null` | +|---|---| +| `label` | Reverts to the global alt text | +| `position` | Reverts to the global display order | +| `disabled` | Reverts to the global visibility setting | +| `extension_attributes.video_content.video_title` | Reverts to the global video title (video entries only) | +| `extension_attributes.video_content.video_description` | Reverts to the global video description (video entries only) | + +**Endpoint:** + +```html +POST http://domain.com/rest/default/V1/products +``` + + + +#### Payload + +```json +{ + "product": { + "sku": "MJ03", + "media_gallery_entries": [ + { + "id": 709, + "media_type": "image", + "label": null, + "position": null, + "disabled": null, + "types": [ + "image", + "small_image", + "thumbnail" + ], + "file": "\/m\/j\/mj03-black_main_12.jpg" + }, + { + "id": 710, + "media_type": "image", + "label": null, + "position": null, + "disabled": null, + "types": [], + "file": "\/m\/j\/mj03-black_alt1_12.jpg" + }, + { + "id": 711, + "media_type": "image", + "label": null, + "position": null, + "disabled": null, + "types": [], + "file": "\/m\/j\/mj03-black_back_12.jpg" + } + ] + } +} +``` + +#### Response + +```json +{ + "sku": "MJ03", + "name": "product name override in default store view", + "media_gallery_entries": [ + { + "id": 709, + "media_type": "image", + "label": "", + "position": 1, + "disabled": false, + "types": [ + "image", + "small_image", + "thumbnail" + ], + "file": "\/m\/j\/mj03-black_main_12.jpg" + }, + { + "id": 710, + "media_type": "image", + "label": "", + "position": 2, + "disabled": false, + "types": [], + "file": "\/m\/j\/mj03-black_alt1_12.jpg" + }, + { + "id": 711, + "media_type": "image", + "label": "", + "position": 3, + "disabled": false, + "types": [], + "file": "\/m\/j\/mj03-black_back_12.jpg" + } + ] +} +``` + +After this call, the **Use Default Value** checkbox is re-enabled for all specified fields in each store view. + +## Add a new image at the store view level + +When you add a new image using the media endpoint, it becomes visible in all store views. + +**Endpoint:** + +```html +POST http://domain.com/rest/default/V1/products/MJ03/media +``` + + + +#### Payload + +```json +{ + "entry": { + "media_type": "image", + "label": "New image label", + "position": 4, + "disabled": false, + "content": { + "base64_encoded_data": "", + "type": "image/png", + "name": "new-image.png" + }, + "types": [] + } +} +``` + +#### Response + +```json +3434 +``` + +The response returns the new image `id`. + +After this call: + +* The new image is visible in all store views. + +* In the **default store view**: Images sort order is no longer using the default value. The new image's `label` and `disabled` are not inheriting. + +* In the **second store view**: all image fields continue to use the default value. + +## Update a media entry at the store view level + +To update a specific image, first retrieve its current data, then send an update. + +**Step 1.** Retrieve the image entry. + +**Endpoint:** + +```html +GET http://domain.com/rest/default/V1/products/MJ03/media/3434 +``` + +**Step 2.** Update the entry with the modified fields. + +**Endpoint:** + +```html +PUT http://domain.com/rest/default/V1/products/MJ03/media/3434 +``` + + + +#### Payload + +```json +{ + "entry": { + "id": 3434, + "media_type": "image", + "label": "Updated label for default store view", + "position": 4, + "disabled": false, + "types": [], + "file": "\/n\/e\/new-image.png" + } +} +``` + +#### Response + +```json +true +``` + +After this call: + +* The image is updated in the **default store view**. +* In the **default store view**: Images sort order continues to not use the default value. +* The **second store view** continues to use the default value (unaffected). + +## Delete a media entry + +Deleting an image entry removes it from the product across all store views. + +**Endpoint:** + +```html +DELETE http://domain.com/rest/default/V1/products/MJ03/media/3434 +``` + +**Response:** + +```json +true +``` + +After this call: + +* The image is deleted from **all store views** +* In the **default store view**: Existing images sort order will go back to using default value. +* The **second store view** continues to use the default value (unaffected). + +## Related resources + +* [Add and manage product images tutorial](/rest/tutorials/image/) + +* [Step 2. Add a new image](new.md) + +* [Step 3. Update an image](update.md)