# Elastic Path Documentation > API, Commerce Manager, Guides and Documentation 🚀 This file contains all documentation content in a single document following the llmstxt.org standard. ## Account Authentication Settings You can use the Account Authentication Settings endpoint to retrieve or modify how settings controlling account and account member authentication. ```mdx-code-block import DocCardList from '@theme/DocCardList'; import {useCurrentSidebarCategory} from '@docusaurus/theme-common'; ``` --- ## Account Management Authentication Commerce provides authentication tokens for an `Account` and an `Account Member`. ```mdx-code-block import DocCardList from '@theme/DocCardList'; import {useCurrentSidebarCategory} from '@docusaurus/theme-common'; ``` --- ## Account Management Introduction import ApiLogo from "@theme/ApiLogo"; import Heading from "@theme/Heading"; import SchemaTabs from "@theme/SchemaTabs"; import TabItem from "@theme/TabItem"; import Export from "@theme/ApiExplorer/Export"; An Account represents the entity that participates in a Commerce transaction. Accounts can have Carts, Orders, Subscriptions, and Addresses. Each account can have multiple account members, which represent users and can transact on behalf of the account. In a typical B2C scenario, an account usually has a single account member. However, this functionality can also be used to support use cases such as family accounts, allowing multiple family members to transact on behalf of their shared account. In a B2B scenario, an account will have multiple members from a business unit, all of whom can transact on behalf of their organization. Accounts can be grouped together using Account Tags, and those tags can be used to apply discounts and promotions. ## Accounts vs Customers Accounts is the next generation of [Customers](/docs/customer-management/customers). Customers are not going anywhere, but accounts offers more capabilities. We recommend using Accounts for any of your new use cases. | Feature | Customers | Accounts | |---------------------------------------------------------------------------------------------|-----------|----------| | B2C Accounts | ✅ | ✅ | | Family Accounts | ⛔️ | ✅ | | B2B Accounts | ⛔️ | ✅ | | Authentication: Shopper impersonation | ⛔️ | ✅ | | Authentication: OpenID support | ✅ | ✅ | | Authentication: One time passwords, and password reset | ⛔️ | ✅ | | Authentication: Configurable token expiry | ⛔️ | ✅ | | Cart association | ✅ | ✅ | | Shopper specific Promotions | Limited | ✅ | | Shopper specific Catalogs | ✅ | ✅ | | Addresses | ✅ | ✅ | | [Personal Data Support (GDPR,CCPA,...)](/docs/api/personal-data/personal-data-introduction) | ✅ | ✅ | Security Scheme Type: http HTTP Authorization Scheme: bearer Contact Elastic Path: [support@elasticpath.com](mailto:support@elasticpath.com) URL: [https://www.elasticpath.com](https://www.elasticpath.com) License MIT --- ## Account Members An `Account Member` resource is a user that you can add to accounts using account memberships. Account members API is read only, and you cannot add users using this API. There is a 1 to 1 correspondence between User Authentication Info and an Account Member, the corresponding objects have the same id. You must use the `user_authentication_info` object to create users in the authentication realm of account authentication settings. For more information on adding account members, see the [Adding Accounts and Account Members](/guides/How-To/Accounts/add-account-and-member) section. ```mdx-code-block import DocCardList from '@theme/DocCardList'; import {useCurrentSidebarCategory} from '@docusaurus/theme-common'; ``` --- ## Account Membership Settings Account Membership Settings allow Account Members to be associated to, at most, N accounts at a time. You can set this value to any number up to 10,000. The default value is 10,000. This setting is only applied to new account memberships. If an account member is added to 3 accounts, and the setting is reduced to 1, the account member remains in the 3 accounts and can no longer be added to more. ```mdx-code-block import DocCardList from '@theme/DocCardList'; import {useCurrentSidebarCategory} from '@docusaurus/theme-common'; ``` --- ## Account Membership The `Account Membership` resource represents the relationship between an account and an account member. This relationship is many to many. Each account can have multiple account members, and each account member can be a member of multiple accounts. ```mdx-code-block import DocCardList from '@theme/DocCardList'; import {useCurrentSidebarCategory} from '@docusaurus/theme-common'; ``` --- ## Account Tags Account Tags are custom labels or metadata that can be attached to accounts to help organize and filter them based on specific attributes or criteria. ```mdx-code-block import DocCardList from '@theme/DocCardList'; import {useCurrentSidebarCategory} from '@docusaurus/theme-common'; ``` --- ## Accounts An Account represents the entity that participates in a Commerce transaction. Accounts can have Carts, Orders, Subscriptions, and Addresses. ```mdx-code-block import DocCardList from '@theme/DocCardList'; import {useCurrentSidebarCategory} from '@docusaurus/theme-common'; ``` --- ## Add Account Tags import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Add Account Tags onto an Account. Please note that after adding a tag to an account, the account member token should be regenerated to reflect the updated account status, allowing other services to react accordingly. See [Account Management Authentication Token](/docs/api/accounts/post-v-2-account-members-tokens). Request --- ## Create an Account Tag import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Create an Account Tag Request --- ## Delete an Account Tag import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Delete an Account Tag Request --- ## Delete an Account Membership import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Delete a membership from an account Request --- ## Delete an Account import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Delete a specific account within a store Request --- ## Get an Account Tag import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Get an Account Tag Request --- ## Get an Account's Tags Relationship import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Get a list of Account Tags on an Account Request --- ## Get a List of Account Memberships of Account Member import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; You can also use `include=account` to retrieve details about the accounts associated with the account memberships. For more information see [including resources](/guides/Getting-Started/includes). You can use pagination with this resource. For more information, see [pagination](/guides/Getting-Started/pagination). ### Filtering The following operators and attributes are available for [filtering](/guides/Getting-Started/filtering) account memberships. | Operator | Description | | :--- | :--- | | `eq` | Checks whether the values of two operands are equal. If the values are equal, the condition is true. | | `like` | Checks if the operand contains the specified string. You can use wildcard characters in operand. | | Attribute | Type | Operator | Example | | :--- | :--- | :--- | :--- | | `account_member_id` | `string` | `eq` / `like` | `eq(account_member_id,00000000-0000-1000-8000-0000000)` | Request --- ## Get an Account Member import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Get an account member from your store Request --- ## Get all Account Members import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Get all account members contained within your store. ### Filtering The following operators and attributes are available for [filtering](/guides/Getting-Started/filtering) account members. | Attribute | Type | Operator | Example | | :--- | :--- | :--- | :--- | | `email` | `string` | `ilike` | `ilike(email,'ronswanson@example.com')` | | `name` | `string` | `ilike` | `ilike(name,'*swan*')` | | `given_name` | `string` | `ilike`/`is_null` | `ilike(given_name,'ron*')` | | `middle_name` | `string` | `ilike`/`is_null` | `is_null(middle_name)` | | `family_name` | `string` | `ilike`/`is_null` | `is_null(family_name)` | Request --- ## Get an Account Membership import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Get an account membership from an account in your store. You can also use `include=account_member` to retrieve details about the account member associated with this account membership. With this option, you can get more information about the account member such as name and email in a single request. For more information see [including resources](/guides/Getting-Started/includes). Request --- ## Get a List of Unassigned Account Members import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Use this resource to get a list of all account members that are not assigned to an account. ### Filtering The following operators and attributes are available for [filtering](/guides/Getting-Started/filtering) unassigned account members. | Operator | Description | | :------- | :--------------------------------------------------------------------------------------------------- | | `eq` | Checks whether the values of two operands are equal. If the values are equal, the condition is true. | | `like` | Checks if the operand contains the specified string. You can use wildcard characters in operand. | | Attribute | Type | Operator | Example | | :-------- | :------- | :------------ | :--------------------------------- | | `email` | `string` | `eq` / `like` | `eq(email,ronswanson@example.com)` | | `name` | `string` | `eq` / `like` | `like(name,*swan*)` | :::note You can use pagination with this resource. For more information, see [pagination](/guides/Getting-Started/pagination). ::: Request --- ## Get all Account Memberships import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; You can also use `include=account_member` to retrieve details about the account members associated with the account memberships. With this option, you can get more information about the account members such as name and email in a single request. For more information see [including resources](/guides/Getting-Started/includes). ### Filtering The following operators and attributes are available for [filtering](/guides/Getting-Started/filtering) account memberships. | Operator | Description | | :--- | :--- | | `eq` | Checks whether the values of two operands are equal. If the values are equal, the condition is true. | | `like` | Checks if the operand contains the specified string. You can use wildcard characters in operand. | | Attribute | Type | Operator | Example | | :--- | :--- | :--- | :--- | | `account_member_id` | `string` | `eq` / `like` | `eq(account_member_id,00000000-0000-1000-8000-0000000)` | Request --- ## Get an Account import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; View a specific account contained within your store Request --- ## Get All Accounts import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Use this endpoint to Get all accounts. You can use pagination with this resource. For more information, see [pagination](/guides/Getting-Started/pagination). ### Filtering The following operators and attributes are available for [filtering](/guides/Getting-Started/filtering) accounts: | Attribute | Operators | Example | |-------------------|-------------------------------|---------------------------------------------------------------| | `id` | `lt`,`le`,`eq`,`gt`,`ge`,`in` | `eq(id,3fa85f64-5717-4562-b3fc-2c963f66afa6)` | | `created_at` | `lt`,`le`,`eq`,`gt`,`ge` | `ge(created_at,2024-04-29T00:00:00.000Z)` | | `updated_at` | `lt`,`le`,`eq`,`gt`,`ge` | `le(updated_at,2024-04-29T00:00:00.000Z)` | | `name` | `eq`,`like` | `like(name,*swan*)` | | `legal_name` | `eq`,`like` | `like(legal_name,*swan*)` | | `registration_id` | `eq`,`like` | `like(registration_id,00000000-0000-1000-8000-*)` | | `external_ref` | `eq`,`like`,`in` | `like(external_ref,16be*)` | | `account_tags` | `contains` | `contains(account_tags,26beb787-be6e-40c3-bbae-9c645820b075)` | Request --- ## Get Account Authentication Settings import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Use this endpoint to view account authentication settings --- ## Get Account Membership Settings import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Use this endpoint to get all account membership settings. --- ## List Account Tags import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Retrieves a list of Account Tags ## Filtering The following operators and attributes are available for [filtering](/guides/Getting-Started/filtering) Account Tags: | Attribute | Operators | Example | |------------------|-------------------------------|-----------------------------------------------| | `id` | `lt`,`le`,`eq`,`gt`,`ge`,`in` | `eq(id,3fa85f64-5717-4562-b3fc-2c963f66afa6)` | | `created_at` | `lt`,`le`,`eq`,`gt`,`ge` | `ge(created_at,2024-04-29T00:00:00.000Z)` | | `updated_at` | `lt`,`le`,`eq`,`gt`,`ge` | `le(updated_at,2024-04-29T00:00:00.000Z)` | | `name` | `eq`,`like` | `eq(name,AccountName)` | ## Sorting The following attributes are available for sorting. When specified, the results are sorted in ascending order based on the value of the field. To sort in descending order, prefix the attribute with `-`, for example, `-updated_at`. The default sort order is `created_at` in descending order. - `id` - `created_at` - `updated_at` - `name` Request --- ## Generate an Account Management Authentication Token import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Commerce provides authentication tokens for anyone using the Account Management APIs, including accounts and account members. For each element in the list returned by the account member authentication API, a token value is returned. In order for a shopper to authenticate as the account, this value should be set as the `EP-Account-Management-Authentication-Token` header when calling Commerce. This header grants access to additional resources associated with the account, such as [carts](/docs/api/carts/account-cart-associations), [orders](/docs/api/carts/orders), [catalogs with associated rules](/docs/api/pxm/catalog/rules), and [addresses](/docs/api/addresses/addresses-introduction). The set of permissions available to a shopper using an Account Management Authentication token is documented in [Permissions](/docs/authentication/tokens/permissions) Commerce provides authentication tokens for an account and an account member using: - OpenID Connect - Username and password - Self signup - One-time password token - Switch account token Request --- ## Create an Account Membership import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; :::caution You can only create up to 1000 account memberships in an account. ::: Request --- ## Create an Account import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; With the account creation endpoint, you have the ability to create accounts which can optionally have another account as a parent. Request --- ## Update an account member import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; This endpoint can be used to update an account member. Request --- ## Update an Account Membership import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; You can update and extend an account member details using [core flows](/docs/api/flows/flows#extend-an-existing-resource). However, you cannot update the `account_member_id` of an account member. Request --- ## Update an Account import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Update the information contained on an account. Request --- ## Update Account Authentication Settings import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Use this endpoint to update account authentication settings Request --- ## Update Account Membership Settings import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Use this endpoint to update account membership settings. Request --- ## Remove Account Tags import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Remove Account Tags from an Account. Please note that after removing a tag from an account, the account member token should be regenerated to reflect the updated status, allowing other services to react accordingly. See [Account Management Authentication Token](/docs/api/accounts/post-v-2-account-members-tokens). Request --- ## Update an Account Tag import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Update an Account Tag Request --- ## Account Addresses The API to organize account addresses. ```mdx-code-block import DocCardList from '@theme/DocCardList'; import {useCurrentSidebarCategory} from '@docusaurus/theme-common'; ``` --- ## Addresses Introduction import ApiLogo from "@theme/ApiLogo"; import Heading from "@theme/Heading"; import SchemaTabs from "@theme/SchemaTabs"; import TabItem from "@theme/TabItem"; import Export from "@theme/ApiExplorer/Export"; The Addresses API allows you to organize account addresses. Addresses are a sub-resource of `account` resources, an account can have multiple addresses, such as home, work, and neighbour. You can use an account address with either [client_credentials access token](/docs/api/authentication/create-an-access-token) or a combination of [implicit access token](/docs/api/authentication/create-an-access-token) and [Account Management authentication](/docs/api/accounts/post-v-2-account-members-tokens) token. Security Scheme Type: http HTTP Authorization Scheme: bearer Contact Elastic Path: [support@elasticpath.com](mailto:support@elasticpath.com) URL: [https://www.elasticpath.com](https://www.elasticpath.com) License MIT --- ## Delete an Account Address import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Delete an address for an Account. Request --- ## Get an Account Address import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Get a specific address for an Account. Request --- ## Get Account Addresses import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Get all addresses for an Account. You can use pagination with this resource. For more information, see [pagination](/guides/Getting-Started/pagination). ### Filtering The following operators and attributes are available for [filtering](/guides/Getting-Started/filtering) addresses: | Attribute | Operators | Example | |----------------|---------------------------------|---------------------------------------| | `name` | `eq`,`in`,`like`,`ilike`,`text` | `ilike(name,"*home*")` | | `first_name` | `eq`,`in`,`like`,`ilike`,`text` | `ilike(first_name,"Ron*")` | | `last_name` | `eq`,`in`,`like`,`ilike`,`text` | `ilike(last_name,"*swan*")` | | `phone_number` | `eq`,`in`,`like`,`ilike`,`text` | `ilike(phone_number,"*555*")` | | `company_name` | `eq`,`in`,`like`,`ilike`,`text` | `ilike(company_name,"*enterprises*")` | | `instructions` | `eq`,`in`,`like`,`ilike`,`text` | `text(instructions,"behind bin")` | | `line_1` | `eq`,`in`,`like`,`ilike`,`text` | `ilike(line_1,"*Sunny Street*")` | | `line_2` | `eq`,`in`,`like`,`ilike`,`text` | `ilike(line_2,"*Unit*")` | | `city` | `eq`,`in`,`like`,`ilike`,`text` | `eq(city,"Sunny Town")` | | `county` | `eq`,`in`,`like`,`ilike`,`text` | `eq(county,"Sunnyville")` | | `region` | `eq`,`in`,`like`,`ilike`,`text` | `eq(region,"California")` | | `postcode` | `eq`,`in`,`like`,`ilike`,`text` | `eq(postcode,"SU33 1YY")` | | `country` | `eq`,`in`,`like`,`ilike`,`text` | `eq(country,"GB")` | Request --- ## Create an Account Address import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Create an address for an Account. Request --- ## Update an Account Address import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Update an address for an Account. Request --- ## Application Keys Introduction import ApiLogo from "@theme/ApiLogo"; import Heading from "@theme/Heading"; import SchemaTabs from "@theme/SchemaTabs"; import TabItem from "@theme/TabItem"; import Export from "@theme/ApiExplorer/Export"; Application keys are used to directly manage access to Organizations and stores. These keys are identified based on their names, and are not associated with a user. You can use application keys to generate `client_credentials` and `implicit tokens`. Unlike [User Credentials](/docs/authentication/security#user-credentials), Application keys are still valid even after a team member is removed from a store or organization. Each organization and store has a specific [rate limit](/guides/Getting-Started/rate-limits). You can fine-tune the performance and availability of your applications that are integrated with our platform by reserving a rate limit for each Application Key. Reserved rate limits ensures that applications using a token generated from that key can make at least that many requests per second. ## Scenarios For example, consider the following two scenarios for using reserved rate limits: - Scenario 1: Suppose you use a key for your store front. You can reduce the risk of customers experiencing throttling while shopping by reserving a majority of your store's rate limit for that store front to ensure a smooth shopping experience. - Scenario 2: If you have a key for the store front but you also need to support several backend processes syncing data across systems, you can reserve a part of your store's rate limit to your store front key. This ensures that the backend process doesn't slow down the store front. Additionally, you can also reserve a rate limit for the key that is associated with most critical backend process. It is important to note that the sum of the reserved value for all keys in your store or organization cannot exceed the total allowed requests per second for that store or organization. For example, suppose a store has a rate limit of 100 requests per second, and there is already a key that has a reserved limit of 80 requests per second. If you try to create a new key with reserved rate limit of 21 requests per second, the request will fail. However, if you reserve only 20 requests per second, it will succeed as it doesn't exceed the store's rate limit. Keys without a reserved rate limits share from the same pool. If the total reserved rate limit across keys reaches the total rate limit for your store or organization, there will be nothing left in the unreserved, shared pool. Keys without a reserved rate limit will experience throttling when they attempt to make requests. Keys with a reserved rate limit can also use this shared pool. Adjustments made to the reserved rate limit may take up to one hour to become effective. The following table describes the management of application keys for organizations and stores. | Organizations | Stores | | --------------- | -------- | | Application keys are granted the same permissions as Org Admins. | Application keys are granted the same permissions as Store Admins. | | Org Admins can view and manage the list of application keys in their organization and all stores belonging to that organization. | Store Admins can view and manage the list of application keys within the store. | | Application keys can be used to manage access to an organization and all stores in the organization. | Application keys can be used to manage access to a store. | ## Best Practices for Application Keys - Assign a descriptive name for the application key associated with its purpose. - Create a unique application key each each distinct type of interactions, such as storefront and back-end interactions. - Do not embed API keys directly in your code. - Do not store API keys in files within your application's source tree. - Regularly review your application keys and delete any that are no longer in use. - Assign a reserved rate limit for your critical application keys. - Do not fully reserve the rate limit for your store or organizations across all keys. Instead, reserve rate limits thoughtfully to ensure that keys without a reserved rate limit can draw from a shared pool when needed. To create your application key, see [Creating an Application Key](/docs/commerce-manager/application-keys/application-keys-cm). Security Scheme Type: http HTTP Authorization Scheme: bearer Contact Elastic Path: [support@elasticpath.com](mailto:support@elasticpath.com) URL: [https://www.elasticpath.com](https://www.elasticpath.com) License MIT --- ## Application Keys You can use application keys to generate `client_credentials` and `implicit` tokens. ```mdx-code-block import DocCardList from '@theme/DocCardList'; import {useCurrentSidebarCategory} from '@docusaurus/theme-common'; ``` --- ## Create an Application Key import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Create an Application Key Request --- ## Delete an Application Key import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Delete an Application Key Request --- ## Get an Application Key import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Get an Application Key Request --- ## List Application Keys import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Retrieves a list of Application Keys Request --- ## Update an Application Key import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Update an Application Key Request --- ## Authentication import ApiLogo from "@theme/ApiLogo"; import Heading from "@theme/Heading"; import SchemaTabs from "@theme/SchemaTabs"; import TabItem from "@theme/TabItem"; import Export from "@theme/ApiExplorer/Export"; All API endpoints require authentication. To authenticate your request, you will need to provide an access token. Access tokens are generated via an [authentication API endpoint](/docs/api/authentication/create-an-access-token). After creating an access token, you can authenticate your request by sending the access token in the `Authorization` header of your request: ```json Authorization: Bearer 212LJ3k0i2382364HIUEjfeJB98yvH ``` :::note Read our [Quick Start guide](/guides/Getting-Started/your-first-api-request) on how to make your first API request. ::: Access tokens expire after 1 hour. You will have to generate a new one. If you’re using our [JavaScript SDK](https://github.com/elasticpath/js-sdk), this is automatically handled for you. ## Client Credentials vs. Implicit Use Case Scenarios There are two authentication methods, `client_credentials` and `implicit`. The `implicit` authentication will generate an access token that has more limited access, restricting access to mostly read-only, whereas the access token from `client_credentials` has full read and write access. Typically, you would use the `implicit` authentication method for client-side browser based applications (i.e. frontend), and `client_credentials` for all administrative tasks (`CRUD`) you need to perform at the backend. ## Shopper Authentication An implicit access token is often used alongside an Account Management authentication token or a Customer token to access resources restricted to a shopper. ### Account Authentication Account Management authentication tokens are available for anyone using the [Account Management APIs](/docs/api/accounts/account-management-introduction). For each element in the list returned by the account member authentication API, a `token` value is returned. In order for a shopper to authenticate as the account, this value should be set as the `EP-Account-Management-Authentication-Token` header when calling Commerce. This header grants access to additional resources associated with the account, such as [carts](/docs/api/carts/account-cart-associations), [orders](/docs/api/carts/get-customer-orders), [catalogs with associated rules](/docs/api/pxm/catalog/rules), and [addresses](/docs/api/addresses/addresses-introduction). The set of permissions available to a shopper using an Account Management Authentication token is documented in [Permissions](/docs/authentication/tokens/permissions#implicit-account-management-authentication-token). For more information on implementing account management authentication tokens, see [Account Management Authentication Tokens](/docs/api/accounts/post-v-2-account-members-tokens). ### Customer Authentication Customer tokens are available for anyone using the [Customer APIs](/docs/customer-management/customers). A customer token provides access to the records of the customer. Use single sign-on or the email address and password of the customer to retrieve the [customer tokens](/docs/customer-management/customer-management-api/customer-tokens). The customer token should be set as the `X-Moltin-Customer-Token` header to access the following APIs: - [Get a Customer](/docs/customer-management/customer-management-api/get-a-customer) - [Update a Customer](/docs/customer-management/customer-management-api/update-a-customer) - [Get Customer Addresses](/docs/api/customer-addresses/get-v-2-customer-addresses) - [Get an Address](/docs/api/customer-addresses/get-v-2-customer-addresses) - [Create an Address](/docs/api/addresses/get-v-2-account-address) - [Update an Address](/docs/api/addresses/put-v-2-account-address) - [Get all Orders](/docs/api/carts/get-customer-orders) - [Get an Order](/docs/api/carts/get-an-order) - [Get Customer Carts](/docs/api/carts/create-a-cart) - [Create an Association between a Customer and a Cart](/docs/api/carts/create-customer-cart-association) - [Delete an Association Between a Customer and a Cart](/docs/api/carts/delete-customer-cart-association) - [Add Promotion to Cart](/docs/api/carts/manage-carts#add-promotion-to-cart) For more information on implementing customer tokens, see [Customer Tokens](/docs/customer-management/customer-management-api/customer-tokens). ## Organization To help with managing stores within an organization, the access token generated for the organization can be used to authenticate requests for any store within the organization. To make a request to a store within the organization: 1. Set the `EP-Org-ID` header with the organization ID 2. Set the `EP-Store-ID` header with the store ID For example, to get all the application keys for a store with ID `9adcc2d3-6a39-4057-bbc1-b036f1d6c735` that is part of the organization with ID `afb3dd03-1c89-4ff8-8611-cf759b15827f`: ```bash curl -X GET 'https://useast.api.elasticpath.com/v2/application-keys' \ -H 'Authorization: Bearer d5525335fedf1b20f081f641d8d32980ec553b5c' \ -H 'EP-Org-ID: afb3dd03-1c89-4ff8-8611-cf759b15827f' \ -H 'EP-Store-ID: 9adcc2d3-6a39-4057-bbc1-b036f1d6c735' ``` ## Authenticating for Use on the Documentation site In order to perform any of the API requests directly on the documentation site, you will need to authenticate to get an access token. After the first request, any subsequent request will continue to use the same access token. Contact Elastic Path: [support@elasticpath.com](mailto:support@elasticpath.com) URL: [https://www.elasticpath.com](https://www.elasticpath.com) License MIT --- ## Create an Access Token import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; ### Client Credentials A `client_credentials` token is used when the credentials are not publicly exposed, usually a server-side language such as PHP or Node.js. This type of authentication enables `CRUD` access to all resources. `client_id` and `client_secret` are created and managed via [Application Keys](/docs/api/application-keys/create-an-application-key). To see the access granted by a `client_credentials` token, refer to [Permissions](/docs/authentication/tokens/permissions). ### Implicit An `implicit` token is typically used for situations where you are requesting data on the client side and you are exposing your public key. When authenticated implicitly, you can only fetch (`GET`) data with live status (products, categories, brands, etc). The `implicit` token is most appropriate for use inside client-side applications, such as JavaScript. :::caution An `implicit` token can be thought of as a **Read only** token. ::: Request --- ## Account Cart Associations You can create associations between an account and one or more carts. After cart associations exist for an account, those carts are accessible across any device. You can delete associations as required. There are two ways to access the cart: with an [Account Management Authentication Tokens](/docs/api/accounts/post-v-2-account-members-tokens) and without one. ### With an `Account Management Authentication` token These endpoints are for users who authenticated implicitly and require an Account Management Authentication token in the header to access the account cart associations APIs. For more information, see the [Account Token](/docs/api/accounts/post-v-2-account-members-tokens) documentation. #### Cart creation Shoppers create carts and can use any of the carts that they created to check out an order. :::note You can create a cart id, name, and description for the cart. The cart requires a name. Ensure that the string length is greater than or equal to one. Use any symbol in the name and description. For cart id, ensure that you follow the guidelines for safe characters. For more information about cart id naming requirements, see [Safe Characters](/guides/Getting-Started/safe-characters). ::: ### Without an `Account Management Authentication` token These endpoints are for users who use the Client Credentials Token and do not require an account management authentication token in the header to access the account cart associations APIs. For more information, see the [Authentication](/docs/authentication/security) documentation. This user acts as a system administrator and can call any account cart association operations for any account and cart. ### Error Codes You might encounter the following response codes, depending on the scenario: * `400` - `The type does not exist or is not listed as account` - Ensure that the type is `account` and is present. * `403` - `Cannot associate more than one account`. * `403` - `Account does not have the required permissions to fulfill this request`. * `403` - `Invalid json payload` - Check JSON input. The request body must be an array `[]`. If the request body is an object, the error is generated. ```mdx-code-block import DocCardList from '@theme/DocCardList'; import {useCurrentSidebarCategory} from '@docusaurus/theme-common'; ``` --- ## Add Custom Discount To Cart Item import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Use this endpoint to add a custom discount to cart item. Custom discounts cannot be combined with Elastic Path promotions. If the cart already contains Elastic Path promotions, remove them before adding custom discounts. Request --- ## Add Tax Item to Bundle Component import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Use this endpoint to add a tax item to a specific bundle component (component product) within a cart item. :::note There is a soft limit of 5 unique tax items per component product at any one time. ::: Request 0.125). You must specify either `rate` or `amount`, but not both.\n","type":"number"},"amount":{"description":"The tax as an absolute amount in the smallest currency unit (e.g., $10 -> 1000). You must specify either `rate` or `amount`, but not both.\n","type":"number"},"type":{"description":"The type of object being returned. Use `tax_item`.","type":"string","const":"tax_item"},"id":{"description":"The unique identifier for this tax item.","type":"string","format":"uuid","readOnly":true}},"title":"CartsItemsTaxesCommon"},{"type":"object","required":["rate"],"properties":{"rate":{"description":"The tax rate as a decimal (12.5% -> 0.125). Required when using rate-based taxation.\n","type":"number","examples":[0.2]},"amount":{"description":"The tax as an absolute amount. Not allowed when rate is specified.\n","type":"number","examples":[1000]}},"not":{"type":"object","required":["amount"],"properties":{"amount":{"type":"number"}}}}]},{"title":"Tax Object (With Amount)","allOf":[{"type":"object","required":["type"],"properties":{"code":{"description":"A unique tax code in this jurisdiction.","type":"string"},"jurisdiction":{"description":"The relevant tax jurisdiction.","type":"string"},"name":{"description":"The name of the tax item.","type":"string"},"rate":{"description":"The tax rate as a decimal (12.5% -> 0.125). You must specify either `rate` or `amount`, but not both.\n","type":"number"},"amount":{"description":"The tax as an absolute amount in the smallest currency unit (e.g., $10 -> 1000). You must specify either `rate` or `amount`, but not both.\n","type":"number"},"type":{"description":"The type of object being returned. Use `tax_item`.","type":"string","const":"tax_item"},"id":{"description":"The unique identifier for this tax item.","type":"string","format":"uuid","readOnly":true}},"title":"CartsItemsTaxesCommon"},{"type":"object","required":["amount"],"properties":{"amount":{"description":"The tax as an absolute amount in the smallest currency unit (e.g., $10 -> 1000). Required when using amount-based taxation.\n","type":"number","examples":[1000]},"rate":{"description":"The tax rate as a decimal. Not allowed when amount is specified.\n","type":"number","examples":[0.2]}},"not":{"type":"object","required":["rate"],"properties":{"rate":{"type":"number"}}}}]}],"examples":[{"type":"tax_item","code":"VAT","jurisdiction":"UK","name":"Value Added Tax","rate":0.2},{"type":"tax_item","code":"EXCISE","jurisdiction":"US","name":"Excise Tax","amount":500}]}},"required":["data"],"title":"CartItemTaxesEntityResponse"},"examples":{"rateTaxItemComponent":{"summary":"Add a rate-based tax item to a bundle component","value":{"data":{"type":"tax_item","code":"VAT","jurisdiction":"UK","name":"Value Added Tax","rate":0.2}}},"amountTaxItemComponent":{"summary":"Add an amount-based tax item to a bundle component","value":{"data":{"type":"tax_item","code":"PST","jurisdiction":"CA-BC","name":"Provincial Sales Tax","amount":250}}}}}},"required":true}} > 0.125). You must specify either `rate` or `amount`, but not both.\n","type":"number"},"amount":{"description":"The tax as an absolute amount in the smallest currency unit (e.g., $10 -> 1000). You must specify either `rate` or `amount`, but not both.\n","type":"number"},"type":{"description":"The type of object being returned. Use `tax_item`.","type":"string","const":"tax_item"},"id":{"description":"The unique identifier for this tax item.","type":"string","format":"uuid","readOnly":true}},"title":"CartsItemsTaxesCommon"},{"type":"object","required":["rate"],"properties":{"rate":{"description":"The tax rate as a decimal (12.5% -> 0.125). Required when using rate-based taxation.\n","type":"number","examples":[0.2]},"amount":{"description":"The tax as an absolute amount. Not allowed when rate is specified.\n","type":"number","examples":[1000]}},"not":{"type":"object","required":["amount"],"properties":{"amount":{"type":"number"}}}}]},{"title":"Tax Object (With Amount)","allOf":[{"type":"object","required":["type"],"properties":{"code":{"description":"A unique tax code in this jurisdiction.","type":"string"},"jurisdiction":{"description":"The relevant tax jurisdiction.","type":"string"},"name":{"description":"The name of the tax item.","type":"string"},"rate":{"description":"The tax rate as a decimal (12.5% -> 0.125). You must specify either `rate` or `amount`, but not both.\n","type":"number"},"amount":{"description":"The tax as an absolute amount in the smallest currency unit (e.g., $10 -> 1000). You must specify either `rate` or `amount`, but not both.\n","type":"number"},"type":{"description":"The type of object being returned. Use `tax_item`.","type":"string","const":"tax_item"},"id":{"description":"The unique identifier for this tax item.","type":"string","format":"uuid","readOnly":true}},"title":"CartsItemsTaxesCommon"},{"type":"object","required":["amount"],"properties":{"amount":{"description":"The tax as an absolute amount in the smallest currency unit (e.g., $10 -> 1000). Required when using amount-based taxation.\n","type":"number","examples":[1000]},"rate":{"description":"The tax rate as a decimal. Not allowed when amount is specified.\n","type":"number","examples":[0.2]}},"not":{"type":"object","required":["rate"],"properties":{"rate":{"type":"number"}}}}]}],"examples":[{"type":"tax_item","code":"VAT","jurisdiction":"UK","name":"Value Added Tax","rate":0.2},{"type":"tax_item","code":"EXCISE","jurisdiction":"US","name":"Excise Tax","amount":500}]}},"required":["data"],"title":"CartItemTaxesEntityResponse"},"examples":{"componentRateTaxItem":{"summary":"Rate-based tax item on bundle component","value":{"data":{"id":"4f4e6d37-8c8c-4a1a-b8a3-6cd2efab12de","type":"tax_item","code":"VAT","jurisdiction":"UK","name":"Value Added Tax","rate":0.2}}}}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","required":["errors"],"properties":{"errors":{"type":"array","items":{"type":"object","required":["status","title"],"properties":{"title":{"type":"string","description":"A brief summary of the error.","examples":["Bad Request"]},"status":{"type":["string","integer"],"description":"The HTTP response code of the error.","examples":["400"]},"detail":{"type":"string","description":"Optional additional detail about the error.","examples":["The field 'name' is required"]},"source":{"type":"string","description":"The field or location that caused the validation error. For JSON schema validation errors, this contains the JSON path to the invalid field (e.g., 'data.name', 'request', 'data.items[0].quantity')."},"meta":{"type":"object","description":"Additional metadata associated with the error. May include arbitrary keys.","properties":{"id":{"type":"string","description":"The resource id associated with the error"},"ids":{"type":"array","items":{"type":"string","description":"The resource ids associated with the error"}},"item_ids":{"type":"array","items":{"type":"string","description":"The cart_item ids associated with the error"}},"shipping_group_id":{"type":"string","description":"The shipping group id associated with the error"},"shipping_group_ids":{"type":"array","items":{"type":"string","description":"The shipping group ids associated with the error"}},"cart_id":{"type":"string","description":"The cart id associated with the error"},"code":{"type":"string","description":"The code associated with the error."},"order_id":{"type":"string","description":"The order id associated with the error."},"sku":{"type":"string","description":"The SKU associated with the error."},"email":{"type":"string","format":"email","description":"The email address associated with the error."},"component_product_id":{"type":"string","format":"uuid","description":"The component product ID associated with the error."},"error-meta-key":{"type":"string","description":"Custom error metadata key used for additional error context (e.g., in payment rejections)."},"value":{"description":"The value associated with the error.","oneOf":[{"type":"string"},{"type":"integer"},{"type":"boolean"},{"type":"object","additionalProperties":true},{"type":"array"}]}}}},"title":"Response.ErrorItem"}}},"title":"Response.ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","required":["errors"],"properties":{"errors":{"type":"array","items":{"type":"object","required":["status","title"],"properties":{"title":{"type":"string","description":"A brief summary of the error.","examples":["Bad Request"]},"status":{"type":["string","integer"],"description":"The HTTP response code of the error.","examples":["400"]},"detail":{"type":"string","description":"Optional additional detail about the error.","examples":["The field 'name' is required"]},"source":{"type":"string","description":"The field or location that caused the validation error. For JSON schema validation errors, this contains the JSON path to the invalid field (e.g., 'data.name', 'request', 'data.items[0].quantity')."},"meta":{"type":"object","description":"Additional metadata associated with the error. May include arbitrary keys.","properties":{"id":{"type":"string","description":"The resource id associated with the error"},"ids":{"type":"array","items":{"type":"string","description":"The resource ids associated with the error"}},"item_ids":{"type":"array","items":{"type":"string","description":"The cart_item ids associated with the error"}},"shipping_group_id":{"type":"string","description":"The shipping group id associated with the error"},"shipping_group_ids":{"type":"array","items":{"type":"string","description":"The shipping group ids associated with the error"}},"cart_id":{"type":"string","description":"The cart id associated with the error"},"code":{"type":"string","description":"The code associated with the error."},"order_id":{"type":"string","description":"The order id associated with the error."},"sku":{"type":"string","description":"The SKU associated with the error."},"email":{"type":"string","format":"email","description":"The email address associated with the error."},"component_product_id":{"type":"string","format":"uuid","description":"The component product ID associated with the error."},"error-meta-key":{"type":"string","description":"Custom error metadata key used for additional error context (e.g., in payment rejections)."},"value":{"description":"The value associated with the error.","oneOf":[{"type":"string"},{"type":"integer"},{"type":"boolean"},{"type":"object","additionalProperties":true},{"type":"array"}]}}}},"title":"Response.ErrorItem"}}},"title":"Response.ErrorResponse"}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"type":"object","required":["errors"],"properties":{"errors":{"type":"array","items":{"type":"object","required":["status","title"],"properties":{"title":{"type":"string","description":"A brief summary of the error.","examples":["Bad Request"]},"status":{"type":["string","integer"],"description":"The HTTP response code of the error.","examples":["400"]},"detail":{"type":"string","description":"Optional additional detail about the error.","examples":["The field 'name' is required"]},"source":{"type":"string","description":"The field or location that caused the validation error. For JSON schema validation errors, this contains the JSON path to the invalid field (e.g., 'data.name', 'request', 'data.items[0].quantity')."},"meta":{"type":"object","description":"Additional metadata associated with the error. May include arbitrary keys.","properties":{"id":{"type":"string","description":"The resource id associated with the error"},"ids":{"type":"array","items":{"type":"string","description":"The resource ids associated with the error"}},"item_ids":{"type":"array","items":{"type":"string","description":"The cart_item ids associated with the error"}},"shipping_group_id":{"type":"string","description":"The shipping group id associated with the error"},"shipping_group_ids":{"type":"array","items":{"type":"string","description":"The shipping group ids associated with the error"}},"cart_id":{"type":"string","description":"The cart id associated with the error"},"code":{"type":"string","description":"The code associated with the error."},"order_id":{"type":"string","description":"The order id associated with the error."},"sku":{"type":"string","description":"The SKU associated with the error."},"email":{"type":"string","format":"email","description":"The email address associated with the error."},"component_product_id":{"type":"string","format":"uuid","description":"The component product ID associated with the error."},"error-meta-key":{"type":"string","description":"Custom error metadata key used for additional error context (e.g., in payment rejections)."},"value":{"description":"The value associated with the error.","oneOf":[{"type":"string"},{"type":"integer"},{"type":"boolean"},{"type":"object","additionalProperties":true},{"type":"array"}]}}}},"title":"Response.ErrorItem"}}},"title":"Response.ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"type":"object","required":["errors"],"properties":{"errors":{"type":"array","items":{"type":"object","required":["status","title"],"properties":{"title":{"type":"string","description":"A brief summary of the error.","examples":["Bad Request"]},"status":{"type":["string","integer"],"description":"The HTTP response code of the error.","examples":["400"]},"detail":{"type":"string","description":"Optional additional detail about the error.","examples":["The field 'name' is required"]},"source":{"type":"string","description":"The field or location that caused the validation error. For JSON schema validation errors, this contains the JSON path to the invalid field (e.g., 'data.name', 'request', 'data.items[0].quantity')."},"meta":{"type":"object","description":"Additional metadata associated with the error. May include arbitrary keys.","properties":{"id":{"type":"string","description":"The resource id associated with the error"},"ids":{"type":"array","items":{"type":"string","description":"The resource ids associated with the error"}},"item_ids":{"type":"array","items":{"type":"string","description":"The cart_item ids associated with the error"}},"shipping_group_id":{"type":"string","description":"The shipping group id associated with the error"},"shipping_group_ids":{"type":"array","items":{"type":"string","description":"The shipping group ids associated with the error"}},"cart_id":{"type":"string","description":"The cart id associated with the error"},"code":{"type":"string","description":"The code associated with the error."},"order_id":{"type":"string","description":"The order id associated with the error."},"sku":{"type":"string","description":"The SKU associated with the error."},"email":{"type":"string","format":"email","description":"The email address associated with the error."},"component_product_id":{"type":"string","format":"uuid","description":"The component product ID associated with the error."},"error-meta-key":{"type":"string","description":"Custom error metadata key used for additional error context (e.g., in payment rejections)."},"value":{"description":"The value associated with the error.","oneOf":[{"type":"string"},{"type":"integer"},{"type":"boolean"},{"type":"object","additionalProperties":true},{"type":"array"}]}}}},"title":"Response.ErrorItem"}}},"title":"Response.ErrorResponse"}}}}}} > --- ## Add Tax Item to Cart import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Use this endpoint to add a tax item to a cart. :::note There is a soft limit of 5 unique tax items per cart item at any one time. ::: Request 0.125). You must specify either `rate` or `amount`, but not both.\n","type":"number"},"amount":{"description":"The tax as an absolute amount in the smallest currency unit (e.g., $10 -> 1000). You must specify either `rate` or `amount`, but not both.\n","type":"number"},"type":{"description":"The type of object being returned. Use `tax_item`.","type":"string","const":"tax_item"},"id":{"description":"The unique identifier for this tax item.","type":"string","format":"uuid","readOnly":true}},"title":"CartsItemsTaxesCommon"},{"type":"object","required":["rate"],"properties":{"rate":{"description":"The tax rate as a decimal (12.5% -> 0.125). Required when using rate-based taxation.\n","type":"number","examples":[0.2]},"amount":{"description":"The tax as an absolute amount. Not allowed when rate is specified.\n","type":"number","examples":[1000]}},"not":{"type":"object","required":["amount"],"properties":{"amount":{"type":"number"}}}}]},{"title":"Tax Object (With Amount)","allOf":[{"type":"object","required":["type"],"properties":{"code":{"description":"A unique tax code in this jurisdiction.","type":"string"},"jurisdiction":{"description":"The relevant tax jurisdiction.","type":"string"},"name":{"description":"The name of the tax item.","type":"string"},"rate":{"description":"The tax rate as a decimal (12.5% -> 0.125). You must specify either `rate` or `amount`, but not both.\n","type":"number"},"amount":{"description":"The tax as an absolute amount in the smallest currency unit (e.g., $10 -> 1000). You must specify either `rate` or `amount`, but not both.\n","type":"number"},"type":{"description":"The type of object being returned. Use `tax_item`.","type":"string","const":"tax_item"},"id":{"description":"The unique identifier for this tax item.","type":"string","format":"uuid","readOnly":true}},"title":"CartsItemsTaxesCommon"},{"type":"object","required":["amount"],"properties":{"amount":{"description":"The tax as an absolute amount in the smallest currency unit (e.g., $10 -> 1000). Required when using amount-based taxation.\n","type":"number","examples":[1000]},"rate":{"description":"The tax rate as a decimal. Not allowed when amount is specified.\n","type":"number","examples":[0.2]}},"not":{"type":"object","required":["rate"],"properties":{"rate":{"type":"number"}}}}]}],"examples":[{"type":"tax_item","code":"VAT","jurisdiction":"UK","name":"Value Added Tax","rate":0.2},{"type":"tax_item","code":"EXCISE","jurisdiction":"US","name":"Excise Tax","amount":500}]}},"required":["data"],"title":"CartItemTaxesEntityResponse"},"examples":{"rateTaxItem":{"summary":"Add a rate-based tax item","value":{"data":{"type":"tax_item","code":"VAT","jurisdiction":"UK","name":"Value Added Tax","rate":0.2}}},"amountTaxItem":{"summary":"Add an amount-based tax item","value":{"data":{"type":"tax_item","code":"GST","jurisdiction":"AU","name":"Goods and Services Tax","amount":1000}}}}}},"required":true}} > 0.125). You must specify either `rate` or `amount`, but not both.\n","type":"number"},"amount":{"description":"The tax as an absolute amount in the smallest currency unit (e.g., $10 -> 1000). You must specify either `rate` or `amount`, but not both.\n","type":"number"},"type":{"description":"The type of object being returned. Use `tax_item`.","type":"string","const":"tax_item"},"id":{"description":"The unique identifier for this tax item.","type":"string","format":"uuid","readOnly":true}},"title":"CartsItemsTaxesCommon"},{"type":"object","required":["rate"],"properties":{"rate":{"description":"The tax rate as a decimal (12.5% -> 0.125). Required when using rate-based taxation.\n","type":"number","examples":[0.2]},"amount":{"description":"The tax as an absolute amount. Not allowed when rate is specified.\n","type":"number","examples":[1000]}},"not":{"type":"object","required":["amount"],"properties":{"amount":{"type":"number"}}}}]},{"title":"Tax Object (With Amount)","allOf":[{"type":"object","required":["type"],"properties":{"code":{"description":"A unique tax code in this jurisdiction.","type":"string"},"jurisdiction":{"description":"The relevant tax jurisdiction.","type":"string"},"name":{"description":"The name of the tax item.","type":"string"},"rate":{"description":"The tax rate as a decimal (12.5% -> 0.125). You must specify either `rate` or `amount`, but not both.\n","type":"number"},"amount":{"description":"The tax as an absolute amount in the smallest currency unit (e.g., $10 -> 1000). You must specify either `rate` or `amount`, but not both.\n","type":"number"},"type":{"description":"The type of object being returned. Use `tax_item`.","type":"string","const":"tax_item"},"id":{"description":"The unique identifier for this tax item.","type":"string","format":"uuid","readOnly":true}},"title":"CartsItemsTaxesCommon"},{"type":"object","required":["amount"],"properties":{"amount":{"description":"The tax as an absolute amount in the smallest currency unit (e.g., $10 -> 1000). Required when using amount-based taxation.\n","type":"number","examples":[1000]},"rate":{"description":"The tax rate as a decimal. Not allowed when amount is specified.\n","type":"number","examples":[0.2]}},"not":{"type":"object","required":["rate"],"properties":{"rate":{"type":"number"}}}}]}],"examples":[{"type":"tax_item","code":"VAT","jurisdiction":"UK","name":"Value Added Tax","rate":0.2},{"type":"tax_item","code":"EXCISE","jurisdiction":"US","name":"Excise Tax","amount":500}]}},"required":["data"],"title":"CartItemTaxesEntityResponse"},"examples":{"rateTaxItem":{"summary":"Rate-based tax item","value":{"data":{"id":"662461ad-ddcb-4dbd-8ed7-ade9aa63b5f9","type":"tax_item","code":"VAT","jurisdiction":"UK","name":"Value Added Tax","rate":0.2}}}}}}},"201":{"description":"Created","headers":{},"content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","title":"Carts Items Taxes Object","description":"A tax item that can be applied to cart items or bundle components. You must specify either a rate (percentage) or an amount (fixed value), but not both.\n","oneOf":[{"title":"Tax Object (With Rate)","allOf":[{"type":"object","required":["type"],"properties":{"code":{"description":"A unique tax code in this jurisdiction.","type":"string"},"jurisdiction":{"description":"The relevant tax jurisdiction.","type":"string"},"name":{"description":"The name of the tax item.","type":"string"},"rate":{"description":"The tax rate as a decimal (12.5% -> 0.125). You must specify either `rate` or `amount`, but not both.\n","type":"number"},"amount":{"description":"The tax as an absolute amount in the smallest currency unit (e.g., $10 -> 1000). You must specify either `rate` or `amount`, but not both.\n","type":"number"},"type":{"description":"The type of object being returned. Use `tax_item`.","type":"string","const":"tax_item"},"id":{"description":"The unique identifier for this tax item.","type":"string","format":"uuid","readOnly":true}},"title":"CartsItemsTaxesCommon"},{"type":"object","required":["rate"],"properties":{"rate":{"description":"The tax rate as a decimal (12.5% -> 0.125). Required when using rate-based taxation.\n","type":"number","examples":[0.2]},"amount":{"description":"The tax as an absolute amount. Not allowed when rate is specified.\n","type":"number","examples":[1000]}},"not":{"type":"object","required":["amount"],"properties":{"amount":{"type":"number"}}}}]},{"title":"Tax Object (With Amount)","allOf":[{"type":"object","required":["type"],"properties":{"code":{"description":"A unique tax code in this jurisdiction.","type":"string"},"jurisdiction":{"description":"The relevant tax jurisdiction.","type":"string"},"name":{"description":"The name of the tax item.","type":"string"},"rate":{"description":"The tax rate as a decimal (12.5% -> 0.125). You must specify either `rate` or `amount`, but not both.\n","type":"number"},"amount":{"description":"The tax as an absolute amount in the smallest currency unit (e.g., $10 -> 1000). You must specify either `rate` or `amount`, but not both.\n","type":"number"},"type":{"description":"The type of object being returned. Use `tax_item`.","type":"string","const":"tax_item"},"id":{"description":"The unique identifier for this tax item.","type":"string","format":"uuid","readOnly":true}},"title":"CartsItemsTaxesCommon"},{"type":"object","required":["amount"],"properties":{"amount":{"description":"The tax as an absolute amount in the smallest currency unit (e.g., $10 -> 1000). Required when using amount-based taxation.\n","type":"number","examples":[1000]},"rate":{"description":"The tax rate as a decimal. Not allowed when amount is specified.\n","type":"number","examples":[0.2]}},"not":{"type":"object","required":["rate"],"properties":{"rate":{"type":"number"}}}}]}],"examples":[{"type":"tax_item","code":"VAT","jurisdiction":"UK","name":"Value Added Tax","rate":0.2},{"type":"tax_item","code":"EXCISE","jurisdiction":"US","name":"Excise Tax","amount":500}]}},"required":["data"],"title":"CartItemTaxesEntityResponse"},"examples":{"amountTaxItem":{"summary":"Amount-based tax item","value":{"data":{"id":"3f3b5e26-7e7e-4d2d-a3a7-5e9b1f72fabc","type":"tax_item","code":"GST","jurisdiction":"AU","name":"Goods and Services Tax","amount":1000}}}}}}},"422":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","required":["errors"],"properties":{"errors":{"type":"array","items":{"type":"object","required":["status","title"],"properties":{"title":{"type":"string","description":"A brief summary of the error.","examples":["Bad Request"]},"status":{"type":["string","integer"],"description":"The HTTP response code of the error.","examples":["400"]},"detail":{"type":"string","description":"Optional additional detail about the error.","examples":["The field 'name' is required"]},"source":{"type":"string","description":"The field or location that caused the validation error. For JSON schema validation errors, this contains the JSON path to the invalid field (e.g., 'data.name', 'request', 'data.items[0].quantity')."},"meta":{"type":"object","description":"Additional metadata associated with the error. May include arbitrary keys.","properties":{"id":{"type":"string","description":"The resource id associated with the error"},"ids":{"type":"array","items":{"type":"string","description":"The resource ids associated with the error"}},"item_ids":{"type":"array","items":{"type":"string","description":"The cart_item ids associated with the error"}},"shipping_group_id":{"type":"string","description":"The shipping group id associated with the error"},"shipping_group_ids":{"type":"array","items":{"type":"string","description":"The shipping group ids associated with the error"}},"cart_id":{"type":"string","description":"The cart id associated with the error"},"code":{"type":"string","description":"The code associated with the error."},"order_id":{"type":"string","description":"The order id associated with the error."},"sku":{"type":"string","description":"The SKU associated with the error."},"email":{"type":"string","format":"email","description":"The email address associated with the error."},"component_product_id":{"type":"string","format":"uuid","description":"The component product ID associated with the error."},"error-meta-key":{"type":"string","description":"Custom error metadata key used for additional error context (e.g., in payment rejections)."},"value":{"description":"The value associated with the error.","oneOf":[{"type":"string"},{"type":"integer"},{"type":"boolean"},{"type":"object","additionalProperties":true},{"type":"array"}]}}}},"title":"Response.ErrorItem"}}},"title":"Response.ErrorResponse"}}}}}} > --- ## Anonymize Orders import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; You can anonymize an order when it is fulfilled, canceled, or fully refunded. When anonymization is successful, Personal Identifiable Information such as customer details, `shipping_address`, and `billing_address` are replaced with *. Request --- ## Bulk Add Custom Discounts to Cart import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; The default value for custom discounts on both the cart and cart items is set to 5 if this parameter is not configured in the store. To verify the custom discount limit value, call [Get all settings](/docs/api/settings/get-v-2-settings) endpoint. To increase the custom discount value, contact [Elastic Path Support team](https://support.elasticpath.com/hc/en-us). Custom discounts cannot be combined with Elastic Path promotions. If the cart already contains Elastic Path promotions, remove them before adding custom discounts. Request --- ## Bulk Add Tax Items to Cart import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Use this endpoint to bulk add tax items to cart items and bundle component products. :::note A cart item can only have a maximum of five tax items. A bundle component product can only have a maximum of five tax items. ::: ### Bundle Component Taxes To add tax items to bundle component products, include a `meta` object with `component_product_id` in each tax item: ```json { "data": [ { "type": "tax_item", "code": "GST", "name": "Goods and Services Tax", "rate": 0.1, "meta": { "component_product_id": "12345678-1234-5678-9012-123456789012" }, "relationships": { "item": { "data": { "type": "cart_item", "id": "cart-item-id" } } } } ] } ``` ### Errors `422 Unprocessable Entity` In this example, when `options.add_all_or_nothing` is set to `true` and if one of cart items is not found or has reached its maximum tax item limit, the following error response is returned: ```json { "status": 422, "title": "Add all or nothing.", "detail": "Add all or nothing set to (true). Could not bulk add tax items to cart." } ``` In this example, if you add more than five tax items to the same cart item, the following error response is returned: ```json { "status": 422, "title": "Tax item not added to cart item.", "detail": "Cannot exceed tax item limit of (5) on cart item.", "meta": { "id": "f88e6370-cb35-40b2-a998-c759f31dec0a" } } ``` `404` In this example, if there is a mismatch between `cart_item`/`custom_item` and the `relationships.item.data.type` specified in the bulk add tax item, the following error response is returned: ```json { "data": [], "errors": [ { "status": 404, "title": "Tax item not added to cart item.", "detail": "Mismatch between bulk tax item type(cart_item) and cart item type(custom_item).", "meta": { "id": "56aab5d1-1dd4-45ed-88ed-4d0cc396b62d" } }, { "status": 404, "title": "Tax item not added to cart item.", "detail": "Mismatch between bulk tax item type(cart_item) and cart item type(custom_item).", "meta": { "id": "56aab5d1-1dd4-45ed-88ed-4d0cc396b62d" } } ] } ``` Request 0.125). You must specify either `rate` or `amount`, but not both.\n","type":"number"},"amount":{"description":"The tax as an absolute amount in the smallest currency unit (e.g., $10 -> 1000). You must specify either `rate` or `amount`, but not both.\n","type":"number"},"type":{"description":"The type of object being returned. Use `tax_item`.","type":"string","const":"tax_item"},"id":{"description":"The unique identifier for this tax item.","type":"string","format":"uuid","readOnly":true}},"title":"CartsItemsTaxesCommon"},{"type":"object","required":["rate"],"properties":{"rate":{"description":"The tax rate as a decimal (12.5% -> 0.125). Required when using rate-based taxation.\n","type":"number","examples":[0.2]},"amount":{"description":"The tax as an absolute amount. Not allowed when rate is specified.\n","type":"number","examples":[1000]}},"not":{"type":"object","required":["amount"],"properties":{"amount":{"type":"number"}}}}]},{"title":"Tax Object (With Amount)","allOf":[{"type":"object","required":["type"],"properties":{"code":{"description":"A unique tax code in this jurisdiction.","type":"string"},"jurisdiction":{"description":"The relevant tax jurisdiction.","type":"string"},"name":{"description":"The name of the tax item.","type":"string"},"rate":{"description":"The tax rate as a decimal (12.5% -> 0.125). You must specify either `rate` or `amount`, but not both.\n","type":"number"},"amount":{"description":"The tax as an absolute amount in the smallest currency unit (e.g., $10 -> 1000). You must specify either `rate` or `amount`, but not both.\n","type":"number"},"type":{"description":"The type of object being returned. Use `tax_item`.","type":"string","const":"tax_item"},"id":{"description":"The unique identifier for this tax item.","type":"string","format":"uuid","readOnly":true}},"title":"CartsItemsTaxesCommon"},{"type":"object","required":["amount"],"properties":{"amount":{"description":"The tax as an absolute amount in the smallest currency unit (e.g., $10 -> 1000). Required when using amount-based taxation.\n","type":"number","examples":[1000]},"rate":{"description":"The tax rate as a decimal. Not allowed when amount is specified.\n","type":"number","examples":[0.2]}},"not":{"type":"object","required":["rate"],"properties":{"rate":{"type":"number"}}}}]}],"examples":[{"type":"tax_item","code":"VAT","jurisdiction":"UK","name":"Value Added Tax","rate":0.2},{"type":"tax_item","code":"EXCISE","jurisdiction":"US","name":"Excise Tax","amount":500}]},{"title":"CartItemRelationship","type":"object","properties":{"relationships":{"type":"object","required":["item"],"properties":{"item":{"type":"object","required":["data"],"properties":{"data":{"type":"object","required":["type","id"],"properties":{"type":{"description":"Specifies the type of item. For example, `custom_item` or `cart_item`.","type":"string","examples":["cart_item"]},"id":{"description":"Specifies the unique identifier of the `cart_item` or `custom_item` in the cart.","type":"string","format":"uuid","examples":["5601a4b1-9d13-42d3-8fb7-03b35169d1b6"]}}}}}}}}}]}},"errors":{"type":"array","items":{"type":"object","required":["status","title"],"properties":{"title":{"type":"string","description":"A brief summary of the error.","examples":["Bad Request"]},"status":{"type":["string","integer"],"description":"The HTTP response code of the error.","examples":["400"]},"detail":{"type":"string","description":"Optional additional detail about the error.","examples":["The field 'name' is required"]},"source":{"type":"string","description":"The field or location that caused the validation error. For JSON schema validation errors, this contains the JSON path to the invalid field (e.g., 'data.name', 'request', 'data.items[0].quantity')."},"meta":{"type":"object","description":"Additional metadata associated with the error. May include arbitrary keys.","properties":{"id":{"type":"string","description":"The resource id associated with the error"},"ids":{"type":"array","items":{"type":"string","description":"The resource ids associated with the error"}},"item_ids":{"type":"array","items":{"type":"string","description":"The cart_item ids associated with the error"}},"shipping_group_id":{"type":"string","description":"The shipping group id associated with the error"},"shipping_group_ids":{"type":"array","items":{"type":"string","description":"The shipping group ids associated with the error"}},"cart_id":{"type":"string","description":"The cart id associated with the error"},"code":{"type":"string","description":"The code associated with the error."},"order_id":{"type":"string","description":"The order id associated with the error."},"sku":{"type":"string","description":"The SKU associated with the error."},"email":{"type":"string","format":"email","description":"The email address associated with the error."},"component_product_id":{"type":"string","format":"uuid","description":"The component product ID associated with the error."},"error-meta-key":{"type":"string","description":"Custom error metadata key used for additional error context (e.g., in payment rejections)."},"value":{"description":"The value associated with the error.","oneOf":[{"type":"string"},{"type":"integer"},{"type":"boolean"},{"type":"object","additionalProperties":true},{"type":"array"}]}}}},"title":"Response.ErrorItem"}},"options":{"title":"Add All Or Nothing Options Object","type":"object","properties":{"add_all_or_nothing":{"description":"When `true`, if an error occurs for any item, no items are added to the cart. When `false`, valid items are added to the cart and the items with errors are reported in the response. Default is `false`.","type":"boolean","examples":[false]}}}}}]},"examples":{"bulkRateTaxItems":{"summary":"Bulk add rate-based tax items to cart items","value":{"data":[{"type":"tax_item","code":"VAT","name":"Value Added Tax","jurisdiction":"UK","rate":0.2,"relationships":{"item":{"data":{"type":"cart_item","id":"5601a4b1-9d13-42d3-8fb7-03b35169d1b6"}}}}],"options":{"add_all_or_nothing":false}}},"bulkAmountTaxItems":{"summary":"Bulk add amount-based tax items to cart and custom items","value":{"data":[{"type":"tax_item","code":"GST","name":"Goods and Services Tax","jurisdiction":"AU","amount":1000,"relationships":{"item":{"data":{"type":"cart_item","id":"1a2b3c4d-5e6f-7a8b-9c0d-abcdefabcdef"}}}},{"type":"tax_item","code":"PST","name":"Provincial Sales Tax","jurisdiction":"CA-BC","amount":250,"relationships":{"item":{"data":{"type":"custom_item","id":"9f8e7d6c-5b4a-3210-fedc-ba9876543210"}}}}],"options":{"add_all_or_nothing":true}}},"bulkBundleComponentTaxItems":{"summary":"Bulk add tax items to bundle component products using meta","value":{"data":[{"type":"tax_item","code":"GST","name":"Goods and Services Tax","jurisdiction":"AU","rate":0.1,"meta":{"component_product_id":"12345678-1234-5678-9012-123456789012"},"relationships":{"item":{"data":{"type":"cart_item","id":"22223333-4444-5555-6666-777788889999"}}}}],"options":{"add_all_or_nothing":false}}}}}},"required":false}} > 0.125). You must specify either `rate` or `amount`, but not both.\n","type":"number"},"amount":{"description":"The tax as an absolute amount in the smallest currency unit (e.g., $10 -> 1000). You must specify either `rate` or `amount`, but not both.\n","type":"number"},"type":{"description":"The type of object being returned. Use `tax_item`.","type":"string","const":"tax_item"},"id":{"description":"The unique identifier for this tax item.","type":"string","format":"uuid","readOnly":true}},"title":"CartsItemsTaxesCommon"},{"type":"object","required":["rate"],"properties":{"rate":{"description":"The tax rate as a decimal (12.5% -> 0.125). Required when using rate-based taxation.\n","type":"number","examples":[0.2]},"amount":{"description":"The tax as an absolute amount. Not allowed when rate is specified.\n","type":"number","examples":[1000]}},"not":{"type":"object","required":["amount"],"properties":{"amount":{"type":"number"}}}}]},{"title":"Tax Object (With Amount)","allOf":[{"type":"object","required":["type"],"properties":{"code":{"description":"A unique tax code in this jurisdiction.","type":"string"},"jurisdiction":{"description":"The relevant tax jurisdiction.","type":"string"},"name":{"description":"The name of the tax item.","type":"string"},"rate":{"description":"The tax rate as a decimal (12.5% -> 0.125). You must specify either `rate` or `amount`, but not both.\n","type":"number"},"amount":{"description":"The tax as an absolute amount in the smallest currency unit (e.g., $10 -> 1000). You must specify either `rate` or `amount`, but not both.\n","type":"number"},"type":{"description":"The type of object being returned. Use `tax_item`.","type":"string","const":"tax_item"},"id":{"description":"The unique identifier for this tax item.","type":"string","format":"uuid","readOnly":true}},"title":"CartsItemsTaxesCommon"},{"type":"object","required":["amount"],"properties":{"amount":{"description":"The tax as an absolute amount in the smallest currency unit (e.g., $10 -> 1000). Required when using amount-based taxation.\n","type":"number","examples":[1000]},"rate":{"description":"The tax rate as a decimal. Not allowed when amount is specified.\n","type":"number","examples":[0.2]}},"not":{"type":"object","required":["rate"],"properties":{"rate":{"type":"number"}}}}]}],"examples":[{"type":"tax_item","code":"VAT","jurisdiction":"UK","name":"Value Added Tax","rate":0.2},{"type":"tax_item","code":"EXCISE","jurisdiction":"US","name":"Excise Tax","amount":500}]},{"title":"CartItemRelationship","type":"object","properties":{"relationships":{"type":"object","required":["item"],"properties":{"item":{"type":"object","required":["data"],"properties":{"data":{"type":"object","required":["type","id"],"properties":{"type":{"description":"Specifies the type of item. For example, `custom_item` or `cart_item`.","type":"string","examples":["cart_item"]},"id":{"description":"Specifies the unique identifier of the `cart_item` or `custom_item` in the cart.","type":"string","format":"uuid","examples":["5601a4b1-9d13-42d3-8fb7-03b35169d1b6"]}}}}}}}}}]}},"errors":{"type":"array","items":{"type":"object","required":["status","title"],"properties":{"title":{"type":"string","description":"A brief summary of the error.","examples":["Bad Request"]},"status":{"type":["string","integer"],"description":"The HTTP response code of the error.","examples":["400"]},"detail":{"type":"string","description":"Optional additional detail about the error.","examples":["The field 'name' is required"]},"source":{"type":"string","description":"The field or location that caused the validation error. For JSON schema validation errors, this contains the JSON path to the invalid field (e.g., 'data.name', 'request', 'data.items[0].quantity')."},"meta":{"type":"object","description":"Additional metadata associated with the error. May include arbitrary keys.","properties":{"id":{"type":"string","description":"The resource id associated with the error"},"ids":{"type":"array","items":{"type":"string","description":"The resource ids associated with the error"}},"item_ids":{"type":"array","items":{"type":"string","description":"The cart_item ids associated with the error"}},"shipping_group_id":{"type":"string","description":"The shipping group id associated with the error"},"shipping_group_ids":{"type":"array","items":{"type":"string","description":"The shipping group ids associated with the error"}},"cart_id":{"type":"string","description":"The cart id associated with the error"},"code":{"type":"string","description":"The code associated with the error."},"order_id":{"type":"string","description":"The order id associated with the error."},"sku":{"type":"string","description":"The SKU associated with the error."},"email":{"type":"string","format":"email","description":"The email address associated with the error."},"component_product_id":{"type":"string","format":"uuid","description":"The component product ID associated with the error."},"error-meta-key":{"type":"string","description":"Custom error metadata key used for additional error context (e.g., in payment rejections)."},"value":{"description":"The value associated with the error.","oneOf":[{"type":"string"},{"type":"integer"},{"type":"boolean"},{"type":"object","additionalProperties":true},{"type":"array"}]}}}},"title":"Response.ErrorItem"}},"options":{"title":"Add All Or Nothing Options Object","type":"object","properties":{"add_all_or_nothing":{"description":"When `true`, if an error occurs for any item, no items are added to the cart. When `false`, valid items are added to the cart and the items with errors are reported in the response. Default is `false`.","type":"boolean","examples":[false]}}}}}]},"examples":{"bulkAddedRateItems":{"summary":"Bulk add response with generated IDs (rate)","value":{"data":[{"id":"98c2b4de-7f33-4b3a-8f2e-8c1b2a3d4e5f","type":"tax_item","code":"VAT","name":"Value Added Tax","jurisdiction":"UK","rate":0.2,"relationships":{"item":{"data":{"type":"cart_item","id":"5601a4b1-9d13-42d3-8fb7-03b35169d1b6"}}}}]}}}}}},"201":{"description":"Created","content":{"application/json":{"schema":{"allOf":[{"title":"CartsBulkTaxes","type":"object","properties":{"data":{"type":"array","items":{"allOf":[{"title":"Carts Items Taxes Object","description":"A tax item that can be applied to cart items or bundle components. You must specify either a rate (percentage) or an amount (fixed value), but not both.\n","oneOf":[{"title":"Tax Object (With Rate)","allOf":[{"type":"object","required":["type"],"properties":{"code":{"description":"A unique tax code in this jurisdiction.","type":"string"},"jurisdiction":{"description":"The relevant tax jurisdiction.","type":"string"},"name":{"description":"The name of the tax item.","type":"string"},"rate":{"description":"The tax rate as a decimal (12.5% -> 0.125). You must specify either `rate` or `amount`, but not both.\n","type":"number"},"amount":{"description":"The tax as an absolute amount in the smallest currency unit (e.g., $10 -> 1000). You must specify either `rate` or `amount`, but not both.\n","type":"number"},"type":{"description":"The type of object being returned. Use `tax_item`.","type":"string","const":"tax_item"},"id":{"description":"The unique identifier for this tax item.","type":"string","format":"uuid","readOnly":true}},"title":"CartsItemsTaxesCommon"},{"type":"object","required":["rate"],"properties":{"rate":{"description":"The tax rate as a decimal (12.5% -> 0.125). Required when using rate-based taxation.\n","type":"number","examples":[0.2]},"amount":{"description":"The tax as an absolute amount. Not allowed when rate is specified.\n","type":"number","examples":[1000]}},"not":{"type":"object","required":["amount"],"properties":{"amount":{"type":"number"}}}}]},{"title":"Tax Object (With Amount)","allOf":[{"type":"object","required":["type"],"properties":{"code":{"description":"A unique tax code in this jurisdiction.","type":"string"},"jurisdiction":{"description":"The relevant tax jurisdiction.","type":"string"},"name":{"description":"The name of the tax item.","type":"string"},"rate":{"description":"The tax rate as a decimal (12.5% -> 0.125). You must specify either `rate` or `amount`, but not both.\n","type":"number"},"amount":{"description":"The tax as an absolute amount in the smallest currency unit (e.g., $10 -> 1000). You must specify either `rate` or `amount`, but not both.\n","type":"number"},"type":{"description":"The type of object being returned. Use `tax_item`.","type":"string","const":"tax_item"},"id":{"description":"The unique identifier for this tax item.","type":"string","format":"uuid","readOnly":true}},"title":"CartsItemsTaxesCommon"},{"type":"object","required":["amount"],"properties":{"amount":{"description":"The tax as an absolute amount in the smallest currency unit (e.g., $10 -> 1000). Required when using amount-based taxation.\n","type":"number","examples":[1000]},"rate":{"description":"The tax rate as a decimal. Not allowed when amount is specified.\n","type":"number","examples":[0.2]}},"not":{"type":"object","required":["rate"],"properties":{"rate":{"type":"number"}}}}]}],"examples":[{"type":"tax_item","code":"VAT","jurisdiction":"UK","name":"Value Added Tax","rate":0.2},{"type":"tax_item","code":"EXCISE","jurisdiction":"US","name":"Excise Tax","amount":500}]},{"title":"CartItemRelationship","type":"object","properties":{"relationships":{"type":"object","required":["item"],"properties":{"item":{"type":"object","required":["data"],"properties":{"data":{"type":"object","required":["type","id"],"properties":{"type":{"description":"Specifies the type of item. For example, `custom_item` or `cart_item`.","type":"string","examples":["cart_item"]},"id":{"description":"Specifies the unique identifier of the `cart_item` or `custom_item` in the cart.","type":"string","format":"uuid","examples":["5601a4b1-9d13-42d3-8fb7-03b35169d1b6"]}}}}}}}}}]}},"errors":{"type":"array","items":{"type":"object","required":["status","title"],"properties":{"title":{"type":"string","description":"A brief summary of the error.","examples":["Bad Request"]},"status":{"type":["string","integer"],"description":"The HTTP response code of the error.","examples":["400"]},"detail":{"type":"string","description":"Optional additional detail about the error.","examples":["The field 'name' is required"]},"source":{"type":"string","description":"The field or location that caused the validation error. For JSON schema validation errors, this contains the JSON path to the invalid field (e.g., 'data.name', 'request', 'data.items[0].quantity')."},"meta":{"type":"object","description":"Additional metadata associated with the error. May include arbitrary keys.","properties":{"id":{"type":"string","description":"The resource id associated with the error"},"ids":{"type":"array","items":{"type":"string","description":"The resource ids associated with the error"}},"item_ids":{"type":"array","items":{"type":"string","description":"The cart_item ids associated with the error"}},"shipping_group_id":{"type":"string","description":"The shipping group id associated with the error"},"shipping_group_ids":{"type":"array","items":{"type":"string","description":"The shipping group ids associated with the error"}},"cart_id":{"type":"string","description":"The cart id associated with the error"},"code":{"type":"string","description":"The code associated with the error."},"order_id":{"type":"string","description":"The order id associated with the error."},"sku":{"type":"string","description":"The SKU associated with the error."},"email":{"type":"string","format":"email","description":"The email address associated with the error."},"component_product_id":{"type":"string","format":"uuid","description":"The component product ID associated with the error."},"error-meta-key":{"type":"string","description":"Custom error metadata key used for additional error context (e.g., in payment rejections)."},"value":{"description":"The value associated with the error.","oneOf":[{"type":"string"},{"type":"integer"},{"type":"boolean"},{"type":"object","additionalProperties":true},{"type":"array"}]}}}},"title":"Response.ErrorItem"}},"options":{"title":"Add All Or Nothing Options Object","type":"object","properties":{"add_all_or_nothing":{"description":"When `true`, if an error occurs for any item, no items are added to the cart. When `false`, valid items are added to the cart and the items with errors are reported in the response. Default is `false`.","type":"boolean","examples":[false]}}}}}]},"examples":{"bulkAddedAmountAndComponentItems":{"summary":"Bulk add response with amount and component taxes","value":{"data":[{"id":"2b3c4d5e-6f70-4a8b-9c0d-1e2f3a4b5c6d","type":"tax_item","code":"GST","name":"Goods and Services Tax","jurisdiction":"AU","amount":1000,"relationships":{"item":{"data":{"type":"cart_item","id":"1a2b3c4d-5e6f-7a8b-9c0d-abcdefabcdef"}}}},{"id":"5e4d3c2b-1a0f-4b8a-9c0d-7f6e5d4c3b2a","type":"tax_item","code":"PST","name":"Provincial Sales Tax","jurisdiction":"CA-BC","amount":250,"relationships":{"item":{"data":{"type":"custom_item","id":"9f8e7d6c-5b4a-3210-fedc-ba9876543210"}}}}]}}}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"type":"object","required":["errors"],"properties":{"errors":{"type":"array","items":{"type":"object","required":["status","title"],"properties":{"title":{"type":"string","description":"A brief summary of the error.","examples":["Bad Request"]},"status":{"type":["string","integer"],"description":"The HTTP response code of the error.","examples":["400"]},"detail":{"type":"string","description":"Optional additional detail about the error.","examples":["The field 'name' is required"]},"source":{"type":"string","description":"The field or location that caused the validation error. For JSON schema validation errors, this contains the JSON path to the invalid field (e.g., 'data.name', 'request', 'data.items[0].quantity')."},"meta":{"type":"object","description":"Additional metadata associated with the error. May include arbitrary keys.","properties":{"id":{"type":"string","description":"The resource id associated with the error"},"ids":{"type":"array","items":{"type":"string","description":"The resource ids associated with the error"}},"item_ids":{"type":"array","items":{"type":"string","description":"The cart_item ids associated with the error"}},"shipping_group_id":{"type":"string","description":"The shipping group id associated with the error"},"shipping_group_ids":{"type":"array","items":{"type":"string","description":"The shipping group ids associated with the error"}},"cart_id":{"type":"string","description":"The cart id associated with the error"},"code":{"type":"string","description":"The code associated with the error."},"order_id":{"type":"string","description":"The order id associated with the error."},"sku":{"type":"string","description":"The SKU associated with the error."},"email":{"type":"string","format":"email","description":"The email address associated with the error."},"component_product_id":{"type":"string","format":"uuid","description":"The component product ID associated with the error."},"error-meta-key":{"type":"string","description":"Custom error metadata key used for additional error context (e.g., in payment rejections)."},"value":{"description":"The value associated with the error.","oneOf":[{"type":"string"},{"type":"integer"},{"type":"boolean"},{"type":"object","additionalProperties":true},{"type":"array"}]}}}},"title":"Response.ErrorItem"}}},"title":"Response.ErrorResponse"}}}}}} > --- ## Bulk Delete Custom Discounts From Cart import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Use this endpoint to bulk delete custom discounts from cart. Request --- ## Bulk Delete Tax Items from Cart import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Use this endpoint to bulk delete all tax items from all cart items and bundle component products in the cart. :::warning This operation will remove ALL tax items from: - All cart items in the cart - All bundle component products within bundle cart items ::: ### Behavior - Removes all tax items from every cart item - Removes all tax items from every component product in bundle cart items - If no tax items exist anywhere in the cart, returns a 404 error ### Errors `404 Not Found` If no tax items exist in the cart (on cart items or component products): ```json { "status": 404, "title": "Resource Not Found", "detail": "No tax items exist in the cart" } ``` Request --- ## Bulk Update Items in Cart import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; The bulk update feature allows shoppers to update an array of items to their cart in one action, rather than updating each item one at a time. Shoppers can update quantity and shipping group details in bulk requests. This minimizes the time for shoppers while updating items to their cart. Shoppers can even update multiple items with the same or different shipping groups to their cart. When you update multiple items that qualify for free gifts in the cart, the corresponding free gifts for all eligible products are also automatically updated in the cart. Request --- ## Cancel a Transaction import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Use this endpoint to cancel or void a pending or authorized transaction. The transaction can be canceled or voided when it is in `pending` and `completed` statuses. :::caution This endpoint works only for Stripe and PayPal and does not work for manual gateway. ::: Request --- ## Capture a Transaction import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Use this endpoint to capture a previously authorized payment. In this step, you can also pass in a custom reference, such as the payment reference from your chosen gateway. Request --- ## Cart Items Products added to a cart are referred to as a `cart_item`. ```mdx-code-block import DocCardList from '@theme/DocCardList'; import {useCurrentSidebarCategory} from '@docusaurus/theme-common'; ``` --- ## Cart Management A Cart contains the product and custom cart items that a user intends to purchase. After a Cart is ready for Checkout, you can use the [Checkout endpoint](/docs/api/carts/checkout) to convert the cart to an order. :::note - Adding, modifying, or removing any cart items, custom items, or promotions always returns the cart meta, calculated using the calculation method. This is useful to update the client with up-to-date totals. - We will automatically delete carts 7 days after they were last updated. - If you do not pass a `X-MOLTIN-CURRENCY` header specifying what currency you would like the cart to use, the products in the cart are converted to your default currency. ::: ```mdx-code-block import DocCardList from '@theme/DocCardList'; import {useCurrentSidebarCategory} from '@docusaurus/theme-common'; ``` --- ## Cart Settings Use Cart Settings to configure cart behavior for your store, including cart expiry, custom discounts, rule promotions, deferred inventory checks, and cart visibility for admins. ```mdx-code-block import DocCardList from '@theme/DocCardList'; import {useCurrentSidebarCategory} from '@docusaurus/theme-common'; ``` --- ## Carts, Checkout, Orders Introduction import ApiLogo from "@theme/ApiLogo"; import Heading from "@theme/Heading"; import SchemaTabs from "@theme/SchemaTabs"; import TabItem from "@theme/TabItem"; import Export from "@theme/ApiExplorer/Export"; A cart contains a list of the products that a shopper adds to the cart while browsing your catalog. In the context of a cart, a selected product is called a cart item. A cart item identifies the product, the product price, the quantity selected, and the total price for the quantity selected. The cart displays a running total of the cost for the selected products plus the calculated tax. You can allow your shoppers to add custom text to a product when adding an item to their carts. This is useful, for example, if you have a product like a T-shirt that can be personalized. See [Add product to cart](/docs/api/carts/manage-carts#add-product-to-cart). After a shopper checks out, the cart is converted to an order, and you can manually delete the cart. If you don't delete the cart, it is purged automatically after seven days. The preview cart feature allows you to set a future date for your shopping cart and view the promotions that will be available during that time period. This feature enables you to validate your promotion settings and observe how they will be applied in the cart. See [Create a Preview Cart](/docs/api/carts/create-a-cart#preview-cart). The following diagram shows a typical cart workflow: ![Shows a cart workflow, starting from adding the first item to a cart, through cart creation and checkout](/assets/cart-workflow.png) ### Multiple Carts Buyers often make purchases based on jobs that they need to perform or outcomes they need to achieve and therefore require more than one shopping cart. For example, a corporate buyer places orders for multiple locations. Each location has a different frequency of ordering and require different products. The buyer can create one cart per location, fill the carts, and then check out the carts quickly. Similarly, shoppers can also create multiple carts for the ease of managing various shopping experiences, such as birthdays or holidays. Each cart is discrete and separate. Any updates or changes to one cart has no effect on the other carts. A cart persists, that is, it stays with the buyer or shopper even after they use the cart in a checkout. Carts remain available after a checkout. Security Scheme Type: http HTTP Authorization Scheme: bearer Contact Elastic Path: URL: [https://elasticpath.com](https://elasticpath.com) License MIT --- ## Checkout API import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; When a Cart is ready for checkout, you can convert the cart to an order. The cart remains and can be modified and checked out again if required. A cart can be checked out with a customer ID, customer object, or with an account by authenticating with the `Client Credentials Token`. After a successful checkout, a response that contains the order is returned. If the cart is linked to a shipping group, the shipping group is also associated with the order after checkout. You can checkout using one of the following methods: - **Customer ID**: You can checkout a cart with an existing customer ID. - **Guest Checkout** (Checkout with Customer Object): You can checkout a cart with an associated customer name and email. - **Checkout with Account**: The shopper authenticates with the `Client Credentials` Token. - **Checkout with Account Management Authentication Token**: The shopper authenticates with the `Implicit Token` and the `EP-Account-Management-Authentication-Token`. :::note - The cart currency is set when the first item is added to the cart. - The product being added to the cart requires a price in the same currency as the other items in the cart. The API returns a 400 error if a price is not defined in the correct currency. - To ensure that a free gift is automatically applied to an order, set the promotion to automatic. The checkout process will not be successful if free gift items are out of stock. See [Errors](#errors) section. ::: :::caution - By default, carts are automatically deleted 7 days after the last update. You can change this setting by [updating cart settings](/docs/api/carts/put-v-2-settings-cart). - Your inventory is modified during checkout and payment of an order. For more information about the changes in the inventory, see the [Inventory](/docs/api/pxm/inventory/inventories-introduction) section. ::: You can pass `order_number` and `external_ref` in the checkout endpoint or when [updating an order](/docs/api/carts/update-an-order). The `order_number` is an optional, user-managed field that is used as an alternative to `order_id`. When processing transactions through Authorize.net, the `order_number` is sent instead of the `order_id`, and it will appear in the invoice number section. If no `order_number` is provided, the `order_id` is sent to Authorize.net on payment by default. There are no duplication restrictions on the `order_number` value. ### Next Steps After a cart has been converted to an Order using either of the previous methods, you most likely want to capture payment for order. See [Paying for an Order](/docs/api/carts/payments). ### Errors The following error response is returned during checkout when an eligible item is added to the cart, and the free gift is out of stock. ```json { "errors": [ { "status": 400, "title": "Insufficient stock", "detail": "There is not enough stock to add gift2 to your cart", "meta": { "id": "f2b68648-9621-45a3-aed6-1b526b0f5beb", "sku": "gift2" } } ] } ``` Request --- ## Checkout The checkout workflow ties together many of the key concepts covered in this section. When a customer initiates the checkout process, an order is created from the cart. The order is incomplete until after a successful payment is made. A complete order can be shipped and the product deducted from inventory counts. ![Checkout workflow](/assets/checkout-flow.png) ### Summary of the checkout workflow 1. Add a product to a cart. A cart and its reference number is generated. 2. Manage the cart items. For example, you might add items, remove items, and change quantities. 3. Check out the cart. An incomplete order is created. 4. Pay for an order: provide billing and shipping details, if you are a new customer. The order is now in the processing status. 5. If using a manual gateway, after you authorize and capture it, Composable Commerce considers the order complete. If you use a third-party integration supported by Composable Commerce (such as Stripe), after the third-party gateway authorizes and captures the payment, the order becomes complete. Usually capture does not occur at the same time as authorization. For more information, see the Capture section. 6. After the order is shipped, you can manually flag it as fulfilled. ### Carts When a product is added to a cart, a cart is generated together with its unique reference ID that on checkout becomes a part of the order ID. If you are using our JavaScript software development kit, generating a cart reference ID is done for you; otherwise, add a cart reference generator to your functionality. ### Promotions and custom items Optionally, apply a promotion code on a cart, or add custom_items to modify the product price (typically to handle taxes, customs, or shipping). ### Checkout You can checkout a cart with an associated customer name and email (customer object). Typically, this would be used for new customers or ones that prefer to shop as guests. Use the `customer.id` checkout option to checkout for an existing customer. After a successful checkout is completed, the response contains an order. Email addresses that either begin or end with a period, or contain consecutive periods, are considered invalid, resulting in the following error: ```json "errors": [ { "status": 400, "source": "data.customer.email", "title": "format", "detail": "Does not match format 'email'" } ] ``` ### Payments On checkout, an incomplete order is created. You can then use a third-party integration to handle your payment gateway. If the payment gateway is supported by Composable Commerce, such as Stripe, the payment is processed externally but handled internally. When a successful validation is returned, Composable Commerce flags the order as complete. If you are using a payment method not officially supported by Composable Commerce, the gateway needs to be implemented and handled manually. After the payment has been authorized and captured either through Commerce Manager or API, the status of an order becomes complete. ### Shipping The status of an order and the status of shipping are handled separately, and so an order can be complete but not shipped. Orders that have not been shipped yet have a status of unfulfilled. This flag is generated automatically by Composable Commerce when an order is created. Currently, you can only update the shipping status manually, through the API. After the order is shipped, flag its shipping status as fulfilled. ### Inventory If enabled, you can manage your stock. As such, your stock is automatically updated as soon as a product is checked out. ```mdx-code-block import DocCardList from '@theme/DocCardList'; import {useCurrentSidebarCategory} from '@docusaurus/theme-common'; ``` --- ## Confirm Order import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Use this endpoint to confirm an order. Confirming an order finalizes it and makes it ready for processing. Request --- ## Confirm Payment import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Confirm Payment serves as a mechanism to synchronize transaction information from the third-party payment provider back to our system. This ensures that Composable Commerce accurately reflects the values from the payment provider. ### Handling 3D Secure Validations for Stripe Payments For Stripe Payments requiring 3D Secure validation, the transaction response will include the `client_parameters` object, which provides credentials to support validation of these payment requests on the payment provider's side. We recommend using the Stripe's client libraries to manage these 3D Secure validations. Once the validation succeeds, proceed with a confirmation request to sync the validated transaction into Composable Commerce and continue with the payment process. Request --- ## Create a Cart import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Creates a cart. Call this endpoint each time a customer creates a cart. Each shopper can have multiple carts. Use the carts API to create a cart. The carts are distinct from one another. Shoppers can add different items to their carts. They can check out one of the carts without affecting the content or status of their other carts. After the shopper checks out the cart, the cart remains available to the shopper. The cart is persistent and stays with the shopper after it is used. You can create a cart to specify custom discounts. You can enable custom discounts when the `discount_settings.custom_discounts_enabled` field is set to `true`. Default is set from cart discount settings for the store. See [Update Cart Settings](/docs/api/carts/put-v-2-settings-cart). You can also create a cart when inventory checks are not performed until checkout by setting the `inventory_settings.defer_inventory_check` field to `true`. Again the default is set from cart discount settings for the store. See [Update Cart Settings](/docs/api/carts/put-v-2-settings-cart). ### Preview Cart You can set a future date for your shopping cart and view the promotions that will be available during that time period. This feature enables you to validate your promotion settings and observe how they will be applied in the cart. :::caution - Once the cart is in preview mode, you cannot revert it to a regular cart. - Carts with `snapshot_date` are same as preview carts. - You cannot checkout a cart that includes a `snapshot_date`. - To delete a promotion preview cart, use [Delete a cart](/docs/api/carts/delete-a-cart) endpoint. - The promotion preview cart has the same expiration time as a regular cart based on the store's [cart settings](/docs/api/carts/put-v-2-settings-cart). - Preview cart interactions skip inventory checks and events, allowing users to preview future carts without impacting related external systems. ::: ### Custom Attributes You can create custom attributes for the cart object to include additional information, enabling promotions that target specific cart attributes. For example: ``` "custom_attributes":{ "membership": { "type": "string", "value": "VIP" } } ``` See [adding cart custom attributes in promotions builder](/docs/commerce-manager/promotions-builder/creating-a-promotion-in-promotions-builder#adding-cart-custom-attributes) Cart custom attributes remain with the corresponding cart for the extent of its lifecycle. These custom attributes carry over to the resulting order objects on checkout and those on carts are deleted with their carts upon cart deletions. Custom attributes can be updated or removed using a PUT request. To delete specific custom attributes, simply exclude the unwanted attribute objects from the PUT request body. ### Contact Email You can attach an email to carts via the `contact.email` field. These values help identify guest shopper carts and, in the case of promotions with maximum usage settings for guest and registered shopper, track per-shopper promotion usages. See [Create Max Uses Per Shopper Promotion Codes](/docs/promotions-builder/promotions-builder-codes/create-max-use-limit-promotion-codes) For example: ``` "contact": { "email": "tester@email.com" } ``` Please note, this value is not supported for registered shopper carts (that is, carts with accounts or customers associated), as these carts already have email values associated via the shopper details. Accordingly, requests to add contact email information to registered shopper carts (and vice versa) result in error messages. ### Errors - `400 Bad Request` : This is returned when the submitted request does not adhere to the expected API contract for the endpoint. - For example, in the case of string fields, this error might indicate issues in the length or format of submitted strings. For more information about valid string fields, refer to Safe Characters section. - In the case of preview carts (those with `snapshot_date`), an error is returned for invalid actions, such as removing the preview date, setting a preview date in the past, or attempting to checkout a cart with a `snapshot_date`. Request --- ## Create an Account Cart Association import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; You can create associations between an account and one or more carts. After cart associations exist for an account, the account can access those carts across any device. Request --- ## Create Stripe Payment Intent for a Cart import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; The Cart Payment Intent feature enables the creation of a Stripe Payment Intent specifically tied to a shopping cart and its subsequent order. This allows Payment Intent users to track payment details from the cart stage and seamlessly maintain consistency in payment information throughout the order stage. Using these features, you can create Payment Intents for their carts, update Payment Intents with final cart details, and synchronize Payment Intents from Stripe to Commerce. :::note - Typically, in Commerce, inventory is allocated at the time of payment initiation after an order is created. However, in the case of Cart Payment Intent, information about the payment is received only upon synchronizing the order from Stripe to Commerce. This may happen after the payment is completed. Therefore, there might be a delay between the payment made and allocation, increasing the chance of paying for items that are not in stock. - There are certain fields you can choose to set up when [creating a payment intent](https://stripe.com/docs/api/payment_intents/create). However, if you decide to update a payment intent, the available options may not be the same as those allowed while creating a payment intent. See [updating a payment intent](https://stripe.com/docs/api/payment_intents/update). ::: The following steps outline the workflow associated with the Payment Intent: 1. [Add items to cart](/docs/api/carts/manage-carts#add-custom-item-to-cart). 1. [Create a Payment Intent for the cart](/docs/api/carts/create-cart-payment-intent). The Payment Intent is created in Stripe, reflecting the cart and transaction details, including currency, amounts, payment type, and any optional Stripe details. The Payment Intent ID is generated and linked to the cart. 1. [Update a Payment Intent](/docs/carts-orders/update-cart-payment-intent). This step is optional but becomes necessary when there are changes in the cart details at the time of payment. It ensures the Payment Intent accurately reflects the current cart details when processing the payments on the front end. 1. [Checkout the cart](/docs/api/carts/checkout). An unpaid order is created, and the Payment Intent ID is linked to the order. 1. [Confirm the order](/docs/carts-orders/confirm-an-order). This is important because after checkout, it is essential to confirm the Payment Intent and synchronize it with Commerce. This results in a corresponding transaction and change in order statuses in Commerce. Additionally, the Payment Intent ID is removed from the order once it is linked via the transaction. ### Best Practices We recommend you follow these practices to maintain consistency and accuracy when using Cart Payment Intent. - After checkout, we recommend clearing the shopping cart. You can achieve this using a [Delete a cart](/docs/api/carts/delete-a-cart) endpoint or [Update a cart](/docs/api/carts/update-a-cart) to remove the Payment Intent ID. This helps to avoid potential issues where subsequent checkouts for the same cart might unintentionally use the previous Stripe Payment Intent ID. - If it is not reasonable to clear the cart immediately after checkout due to several subsequent, duplicate checkouts to the same cart, ensure that you only synchronize the Payment Intent when finalizing the order. Each order confirmation is unaware of the others, and syncing Payment Intent IDs for each confirmation can lead to duplicate transactions in Commerce. In other words, if you synchronize Payment Intents for earlier versions of a repeated checkout, you'll end up with multiple orders from the same cart, each having transactions linked to the same Payment Intent. - To pay the entire amount at once, use the [Update Cart Payment Intent](/docs/carts-orders/update-cart-payment-intent) endpoint to update the Stripe Payment Intent with the final cart details when preparing to take the payment. Doing so, ensures that the Payment Intent accurately reflects the current cart details when processing payments on the front end. We do not recommend calling the [Update Cart Payment Intent](/docs/carts-orders/update-cart-payment-intent) for each individual change in the cart, as this can lead to more requests and may slow down the front-end performance. Request --- ## Create a Customer Cart Association import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; You can create associations between a customer and one or more carts. After cart associations exist for a customer, the customer can access those carts across any device. Request --- ## Create a shipping group for an order import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Create a new shipping group for an order Request --- ## Create a new shipping group for a cart import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Create a new shipping group for a cart Request --- ## Custom Discounts With custom discounts, you can allow your shoppers to apply discounts from external services to their purchases. To apply custom discounts to carts and cart items, you need to set `custom_discounts_enabled` field to `true` in your [Cart Settings](/docs/api/carts/put-v-2-settings-cart). You cannot add custom discounts to an empty cart. :::caution - You can apply up to five custom discounts to cart and cart item. - The stores that use [simple calculation method](/guides/How-To/Carts/calculate-totals) do not support custom discounts. ::: ```mdx-code-block import DocCardList from '@theme/DocCardList'; import {useCurrentSidebarCategory} from '@docusaurus/theme-common'; ``` --- ## Customer Cart Associations You can create associations between a customer and one or more carts. After cart associations exist for a customer, those carts are accessible across any device. You can delete associations as required. There are two ways to access the cart: with a customer token and without one. ### With a `customer` token These endpoints are for users who authenticated implicitly and require a customer token in the header to access the customer cart associations APIs. For more information, see the [Customer Token](/docs/customer-management/customer-management-api/customer-tokens) documentation. #### Cart creation Shoppers create carts and can use any of the carts that they created to check out an order. :::note You can create a cart id, name, and description for the cart. The cart requires a name. Ensure that the string length is greater than or equal to one. Use any symbol in the name and description. For cart id, ensure that you follow the guidelines for safe characters. For more information about cart id naming requirements, see [Safe Characters](/guides/Getting-Started/safe-characters). ::: ### Without a `customer` token These endpoints are for users who use the Client Credentials Token and do not require a Customer token in the header to access the customer cart associations APIs. For more information, see the [Authentication](/docs/authentication/security) documentation. This user acts as a system administrator and can call any customer cart association operations for any customer and cart. ### Error Codes You might encounter the following response codes, depending on the scenario: * `400` - `The type does not exist or is not listed as customer` - Ensure that the type is `customer` and is present. * `403` - `Cannot associate more than one customer`. * `403` - `Customer does not have the required permissions to fulfill this request`. * `403` - `Invalid json payload` - Check JSON input. The request body must be an array `[]`. If the request body is an object, the error is generated. ```mdx-code-block import DocCardList from '@theme/DocCardList'; import {useCurrentSidebarCategory} from '@docusaurus/theme-common'; ``` --- ## Delete a Cart Item import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Use this endpoint to delete a cart item. Request --- ## Delete a Cart import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; You can delete a cart, including the items, name, description, and remove all associations. ### Errors The following error message is received when you attempt to delete a cart that is associated with a customer. Before deletion, ensure that the cart is disassociated. ```json message: { errors: [ { status: 400, title: 'Last cart', detail: 'This is the last cart associated with a customer and it cannot be deleted, try disassociating instead' } ] } ```` Request --- ## Delete a Promotion via Promotion Code import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; You can remove promotion code from a cart if it was applied manually. This endpoint does not work if the promotion is applied automatically. Request --- ## Delete a Tax Item import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Use this endpoint to delete a tax item. Request --- ## Delete Account Cart Association import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; You can delete an association between an account and a cart. Request --- ## Delete all Cart Items import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; A shopper can clean up their cart, deleting custom items, promotions, and so on, while the empty cart remains available. The cart id, name, description, and any account or customer associations persist. The shopper can continue to add items to the cart. Request --- ## Delete Cart Shipping Group import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Deletes a shipping group from a cart. You cannot delete a shipping group that is attached to cart items. You must first remove the shipping group from all cart items before deleting the shipping group. Request --- ## Delete Custom Discount From Cart Item import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Use this endpoint to delete custom discount from cart item. Request --- ## Delete Custom Discount From Cart import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Use this endpoint to delete custom discount from cart. Request --- ## Delete Customer Cart Association import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; You can delete an association between a customer and a cart. Request --- ## Delete Tax Item from Bundle Component import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Use this endpoint to delete a tax item from a specific bundle component (component product) within a cart item. Request --- ## Get a Cart import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Use this endpoint to retrieve a specific cart. If a cart ID does not exist, a new cart will be automatically created. If the cart is associated with shipping groups, calling this endpoint displays the associated shipping group IDs in the `relationships` section. You can easily get a new or existing cart by providing the unique cart reference in the request. If the cart is associated with shipping groups, calling this endpoint displays the associated shipping group IDs in the relationships section. :::note - The default cart name is Cart. However, you can update the cart name as required. Ensure that the string length of the name is greater than or equal to one. Follow the safe character guidelines for name and description naming. For more information about cart ID naming requirements, see the [Safe Characters](/guides/Getting-Started/safe-characters) section. - Outside of the JS-SDK, we don't handle creating cart references. You need to create your own. ::: :::caution An empty cart is returned for any carts that don't currently exist. For more information about the cart items object, see [Get Cart Items](/docs/api/carts/get-cart-items). ::: ### Query parameters | Name | Required | Type | Description | |:----------|:---------|:---------|:-------------------------------------------| | `include` | Optional | `string` | Comma-delimited string of entities that can be included. The information included are `items`,`tax_items`, `custom_discounts`, or `promotions`. | Request --- ## Get a Transaction import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Retrieves a transaction Request --- ## Get an Order import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Use this endpoint to retrieve a specific order. ### Includes You can include related resources with the order response by using the `include` query parameter. | Name | Required | Type | Description | |:----------|:---------|:---------|:------------| | `include` | Optional | `string` | Comma-delimited string of entities that can be included. The included options are `items`, `tax_items`, `custom_discounts`, or `promotions`. | Request --- ## Get Cart Items import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Use this endpoint to retrieve cart items. If the cart is associated with shipping groups, calling this endpoint displays the associated shipping group IDs. You can use this endpoint to retrieve the breakdown of cart items by promotion ID. For example, if you have Promotions Standard item discount with code *sale2024*, Rule Promotions item discount with code *sale2024*, and Rule Promotions cart discount with code *sale2024*, the `discounts.constituents` field in the response example will show the breakdown of the same promotion code used in both Promotions Standard and Rule Promotions. ```json "data": [ { "id": "98de010d-dd10-4fa5-a070-0b9bcdc72974", "type": "cart_item", "product_id": "5a4662d2-9a2b-4f6e-a215-2970db914b0c", "name": "sku1", "description": "sku1", "sku": "sku1", "slug": "sku1", "image": { "mime_type": "", "file_name": "", "href": "" }, "quantity": 1, "manage_stock": false, "unit_price": { "amount": 10000, "currency": "USD", "includes_tax": false }, "value": { "amount": 10000, "currency": "USD", "includes_tax": false }, "discounts": [ { "amount": { "amount": -2000, "currency": "USD", "includes_tax": false }, "code": "sale2024", "id": "e4d929d5-f471-4317-9a86-a84a6c572b44", "promotion_source": "rule-promotion", "is_cart_discount": true }, { "amount": { "amount": -1000, "currency": "USD", "includes_tax": false }, "code": "sale2024", "id": "de19a043-a6da-4bde-b896-d17e16b77e25", "promotion_source": "rule-promotion" }, { "amount": { "amount": -1000, "currency": "USD", "includes_tax": false }, "code": "sale2024", "id": "509295ee-2971-45b6-801e-95df09756989" }, { "amount": { "amount": -1000, "currency": "USD", "includes_tax": false }, "code": "sale2024", "id": "ca79e606-7ecd-41ac-9478-af4c8c28c546", "promotion_source": "rule-promotion", "is_cart_discount": true } ], "links": { "product": "https://useast.api.elasticpath.com/v2/products/5a4662d2-9a2b-4f6e-a215-2970db914b0c" }, "meta": { "display_price": { "with_tax": { "unit": { "amount": 5000, "currency": "USD", "formatted": "$50.00" }, "value": { "amount": 5000, "currency": "USD", "formatted": "$50.00" } }, "without_tax": { "unit": { "amount": 5000, "currency": "USD", "formatted": "$50.00" }, "value": { "amount": 5000, "currency": "USD", "formatted": "$50.00" } }, "tax": { "unit": { "amount": 0, "currency": "USD", "formatted": "$0.00" }, "value": { "amount": 0, "currency": "USD", "formatted": "$0.00" } }, "discount": { "unit": { "amount": -5000, "currency": "USD", "formatted": "-$50.00" }, "value": { "amount": -5000, "currency": "USD", "formatted": "-$50.00" } }, "without_discount": { "unit": { "amount": 10000, "currency": "USD", "formatted": "$100.00" }, "value": { "amount": 10000, "currency": "USD", "formatted": "$100.00" } }, "discounts": { "sale2024": { "amount": -5000, "currency": "USD", "formatted": "-$50.00", "constituents": { "509295ee-2971-45b6-801e-95df09756989": { "amount": -1000, "currency": "USD", "formatted": "-$10.00" }, "ca79e606-7ecd-41ac-9478-af4c8c28c546": { "amount": -1000, "currency": "USD", "formatted": "-$10.00" }, "de19a043-a6da-4bde-b896-d17e16b77e25": { "amount": -1000, "currency": "USD", "formatted": "-$10.00" }, "e4d929d5-f471-4317-9a86-a84a6c572b44": { "amount": -2000, "currency": "USD", "formatted": "-$20.00" } } } } }, "timestamps": { "created_at": "2024-05-24T18:00:58Z", "updated_at": "2024-05-24T18:00:58Z" } }, "catalog_id": "09b9359f-897f-407f-89a2-702e167fe781", "catalog_source": "pim" } ``` Request --- ## Get Carts import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Retrieves a list of carts. The carts returned depend on the authentication method used: | Authentication Method | Header | Returns | | :--- | :--- | :--- | | **Customer Token** | `X-Moltin-Customer-Token` | Carts for the specified customer. See [Customer Tokens](/docs/customer-management/customer-management-api/customer-tokens). | | **Account Token** | `EP-Account-Management-Authentication-Token` | Carts for the specified account. See [Account Management Token](/docs/api/accounts/post-v-2-account-members-tokens). | | **Client Credentials** | `Authorization: Bearer ` | All carts or only registered carts, controlled by the `show_all_carts` setting. See [Cart Settings](/docs/api/carts/put-v-2-settings-cart). | **Client Credentials Behavior:** - When `show_all_carts` is `true`: Returns all carts in the store. - When `show_all_carts` is `false`: Returns only registered carts (associated with customers or accounts). **Sorting** Carts are sorted in descending order by `updated_date`. For more information, see [Pagination](/guides/Getting-Started/pagination). Request --- ## Get all Orders import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; This endpoint returns all orders with custom flow fields. The pagination offset is set to fetch a maximum of 10,000 orders. If the store has 10,000 orders, and you fetch the orders without using filters, an error is returned. Use a filter to view orders when the order is beyond the 10,000 mark. :::note - Pass the `X-Moltin-Customer-Token` header to limit orders to a specific customer. See [Customer Tokens](/docs/customer-management/customer-management-api/customer-tokens). - Pass the `EP-Account-Management-Authentication-Token` header to limit orders to a specific account. See [Account Management Token](/docs/api/accounts/post-v-2-account-members-tokens). - You can use pagination with this resource. For more information, see [pagination](/guides/Getting-Started/pagination). ::: ### Filtering The following operators and attributes are available for filtering orders. | Attribute | Type | Operator | Example | | :--- | :--- | :--- | :--- | | `status` | `string` | `eq` | `eq(status,complete)` | | `payment` | `string` | `eq` | `eq(payment,paid)` | | `shipping` | `string` | `eq` | `eq(shipping,unfulfilled)` | | `name` (`customer.name`) | `string` | `eq` / `like` | `like(name,Brad*)` | | `email` (`customer.email`) | `string` | `eq` / `like` | `like(email,*@elasticpath.com)` | | `customer_id` | `string` | `eq` / `like` | `eq(customer_id, e5a0d684-a4af-4919-a348-f66b0b4955e0)` | | `account_id` | `string` | `eq` / `like` | `eq(account_id,3d7200c9-a9bc-4085-9822-63e80fd94a09)` | | `account_member_id` | `string` | `eq` / `like` | `eq(account_member_id,2a8a3a92-2ccd-4b2b-a7af-52d3896eaecb)` | | `contact.name` | `string` | `eq` / `like` | `eq(name,John Doe)` | | `contact.email` | `string` | `eq` / `like` | `eq(email,John Doe)` | | `shipping_postcode` | `string` | `eq` / `like` | `like(shipping_postcode,117*)` | | `billing_postcode` | `string` | `eq` / `like` | `like(billing_postcode,117*)` | | `with_tax` | `integer` | `gt`/`ge`/`lt`/`le` | `ge(with_tax,10000)` | | `without_tax` | `integer` | `gt`/`ge`/`lt`/`le` | `ge(without_tax,10000)` | | `currency` | `string` | `eq` | `eq(currency,USD)` | | `product_id` | `string` | `eq` | `eq(product_id,6837058c-ae42-46db-b3c6-7f01e0c34b40)` | | `product_sku` | `string` | `eq` | `eq(product_sku,deck-shoe-001)` | | `created_at` | `date` | `eq` / `gt` / `ge`/ `le` / `lt` | `gt(created_at,YYYY-MM-DD)` | | `updated_at` | `date` | `eq` / `gt` / `ge`/ `le`/ `lt` | `lt(updated_at,YYYY-MM-DD)` | | `external_ref` | `string` | `eq` / `like` | `like(external_ref, 16be*)` | | `order_number` | `string` | `eq` / `like` | `like(order_number, 123*)` | ### Includes You can include related resources with the order response by using the `include` query parameter. | Name | Optional | Type | Description | |:-----|:---------|:-----|:------------| | `include` | Optional | `string` | Comma-delimited string of entities that can be included. The information included are `items`, `tax_items`, `custom_discounts`, or `promotions`. | Request --- ## Get Order Items import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Use this endpoint to retrieve order items. ### Includes You can include related resources with the order items response by using the `include` query parameter. | Name | Required | Type | Description | |:----------|:---------|:---------|:------------| | `include` | Optional | `string` | Comma-delimited string of entities that can be included. The included options are `tax_items`, `custom_discounts`, or `promotions`. | Request --- ## Retrieve all shipping groups for an order import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Retrieve all shipping groups for an order Request --- ## Get Order Transactions import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Get order transactions Request --- ## Retrieve a specific shipping group for a cart import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Retrieve a specific shipping group for a cart Request --- ## Retrieve a specific shipping group for an order import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Retrieve a specific shipping group for an order Request --- ## Retrieve all shipping groups for a cart import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Retrieve all shipping groups for a cart Request --- ## Get Cart Settings by Store ID import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Retrieves cart settings for the specified store. Request --- ## Get Cart Settings import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Retrieves cart settings. --- ## Add Items to Cart import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; ### Add Product to Cart Adding a Product to Cart is the most common Cart action. If you want to add any custom products or promotions, you need to do that as a separate action. #### Dynamic Bundles A bundle is a purchasable product that is composed of a combination of two or more products that you want to sell together. You can create multiple components within a bundle. Each component can have one or more options. Each option is a product and a quantity. You can configure minimum and/or maximum values for the number of product options in a component that your shoppers can select. For example, you can enable a shopper to select 1 or more product options from a list of 10. These are called [dynamic bundles](/docs/api/pxm/products/products#dynamic-bundles). Your dynamic bundles are displayed in your published catalogs. 1. Use the configure a shopper endpoint to allow shoppers to make their selections from a bundle. 2. In the response of the configure a shopper, the `bundle_configuration` object contains the bundle selections a shopper has made. 3. In the add a product to cart request, use the `bundle_configuration` object to add the customers selections to a cart. ```json "bundle_configuration": { "selected_options": { "games": { "d7b79eb8-19d8-45ea-86ed-2324a604dd9c": 1 }, "toys": { "0192ccdd-6d33-4898-87d7-c4d87f2bf8ea": 1, "1aea6f97-f0d9-452c-b3c1-7fb5629ead82": 1 } } } ``` When a cart is checked out, the options a shopper selected are added to the order. See [order items](/docs/api/carts/get-order-items). #### Personalized Products You can allow shoppers to personalize their goods by adding custom text inputs to products directly. This feature is particularly useful for customizable items, such as personalized T-shirts or greeting cards. You can use this functionality by leveraging the `custom_inputs` attribute, and defining the details and validation rules for the custom text. First, you must configure a `custom_inputs` attribute when creating a new product or updating an existing product. Once you have defined your custom inputs on a product, you must configure the custom inputs in your orders. For example, you may sell T-shirts that can have personalized text on the front and back of the shirt. ```json { "data": { "type": "product", "attributes": { "custom_inputs": { "front": { "name": "T-Shirt Front", "validation_rules": [ { "type": "string", "options": { "max_length": 50 } } ], "required": false }, "back": { "name": "T-Shirt Back", "validation_rules": [ { "type": "string", "options": { "max_length": 50 } } ], "required": false } } } } } ``` If the same product has different `custom_inputs` attributes, then these are added as separate items in a cart. The `custom_inputs` attribute is stored in the cart item and the text for `custom_input` must not exceed 255 characters in length. When a cart is checked out, the `custom_inputs` attribute becomes part of the order. #### Limitations on Usage of `custom_inputs` with Specific Promotion Types When you add products to a cart with `custom_inputs`, there are certain limitations on usage of the `custom_inputs` with the following promotion types: - For [Free Gift Promotions](/docs/api/promotions/create-a-promotion), you can add `custom_inputs` to gift items. - For [Fixed Bundle Discount Promotions](/docs/api/promotions/create-a-promotion), the promotion applies as long as the cart contains the bundle SKUs even when there are different `custom_inputs`. - For [X for Y Discount Promotion and X for amount discount promotion](/docs/api/promotions/create-a-promotion), the promotion applies when there are two SKUs with the same `custom_inputs`. The promotion does not apply when there are different `custom_inputs` and the SKUs are in different line items. #### Stock locations When adding to a cart it is possible to specify which [stock location](/docs/api/pxm/inventory_mli/inventories-introduction?#multi-location-inventories) should be used for tracking inventory for that product by specifying its slug in `location`. This might represent the warehouse a product is shipped from or the store holding the stock in a Buy Online Pick Up In Store scenario. Each line item is restricted to a single stock location. If the same product is added with a different location then the most recently-specified location will be used for the total quantity of that line item. :::note - Any requests to add a product to cart returns the collection of cart items. - [Tax items](/docs/api/carts/tax-items) may optionally be added with the product. Only administrators with [client_credentials access tokens](/docs/api/authentication/create-an-access-token) are able to do this. If included, they replace any existing taxes on the product. - The cart currency is set when the first item is added to the cart. - The product being added to the cart requires a price in the same currency as the other items in the cart. The API returns a 400 error if a price is not defined in the correct currency. - A cart can contain a maximum of 100 unique items. Items include products, custom items, tax items, and promotions. - There are a number of actions that happen to your inventory when checking out and paying for an order. For more information, see the [Inventory](/docs/api/pxm/inventory/inventories-introduction) documentation. ::: ### Including Resources When you make an `Add Product to Cart` request to the catalog-view service, you can obtain details of the component products. If you include the optional parameter `include=component_products` in the request, the response will include details for each component product. When a bundle with selected component products is added to a cart, the cart displays both the bundle pricing and component product IDs. The response example is returned with a new field called `component_products` under `bundle_configuration`, which is a list of component products that the user has selected for dynamic bundles. | Parameter | Required | Description | |:------------------------|:-------------|:-------------------| | `component_products` | Optional | The component product data and key attribute data, such as SKU or slug, to return for component products in a product bundle. | | `main_image` | Optional | The main images associated with a product. | | `files` | Optional | Any files associated with a product. | ```json "bundle_configuration": { "selected_options": { "mixed-shirts": { "16a6cc14-6ebb-4156-9973-e6a0f92f5731": 3, "55037cc5-f382-4039-95c6-1e04ac0351d3": 2, "standard-shirts" "70f1c9d2-c580-4839-bd6c-a0a9b91d5159": 5 } }, "component_products": [ { "id": "16a6cc14-6ebb-4156-9973-e6a0f92f5731", "type": "product", "attributes": { "name": "Red T-shirt", "description": "Standard red t-shirt.", "slug": "red-t-shirt-slug", "sku": "red-t-shirt-sku", "status": "live", "commodity_type": "physical" }, "meta": { "display_price": { "without_tax": { "amount": 500, "currency": "USD", "formatted": "$5.00" } } } }, { "id": "55037cc5-f382-4039-95c6-1e04ac0351d3", "type": "product", "attributes": { "name": "Blue T-shirt", "description": "Standard blue t-shirt.", "slug": "blue-t-shirt-slug", "sku": "blue-t-shirt-sku", "status": "live", "commodity_type": "physical" }, "meta": { "display_price": { "without_tax": { "amount": 500, "currency": "USD", "formatted": "$5.00" } } } }, { "id": "70f1c9d2-c580-4839-bd6c-a0a9b91d5159", "type": "product", "attributes": { "name": "White T-shirt", "description": "Standard white t-shirt.", "slug": "white-t-shirt-slug", "sku": "white-t-shirt-sku", "status": "live", "commodity_type": "physical" }, "meta": { "display_price": { "without_tax": { "amount": 500, "currency": "USD", "formatted": "$5.00" } } } } ] } ``` See [Including Resources](https://elasticpath.dev/guides/Getting-Started/includes). ### Add Subscription to Cart To add a subscription to your cart, you need to provide the ID of the subscription offering, and the ID of the pricing option and plan within that offering that you want to subscribe to. ```json { { "data": { "id": "5b9be99f-1c94-4ddd-9718-81adab0cc3e0", "type": "subscription_item", "quantity": 1, "subscription_configuration": { "plan": "dfa31307-748c-4369-8571-709f924a0807", "pricing_option": "40010dde-2f38-489b-8b3f-14a13cbfb431" } } } ``` The price of the subscription item in the cart reflects the cost of the subscription's initial billing period. Once the cart has been checked out and the order paid for, the subscription will be automatically created in the subscriptions service. ### Add Custom Item to Cart You can add a custom item to the cart when you don't manage things like shipping, taxes and inventory in Commerce. For [Shipping Groups](/docs/ship-groups/shipping-groups/index), once you have created a [cart shipping group](/docs/ship-groups/shipping-groups/shipping-groups-api/create-cart-shipping-group), you need to link it to the cart items. This is important, because it is necessary to associate items with shipping groups in order to include shipping groups in the corresponding cart, order, and totals. :::note - Custom Cart Items are available when using [implicit access tokens](/docs/api/authentication/create-an-access-token). Ensure that you always check each order has the correct details for each item, most importantly, price. ::: ### Add Promotion to Cart You can use the Promotions API to apply discounts to your cart as a special cart item type. Any requests to add a product to cart will return a collection of cart items. There are certain limitations on usage of the `custom_inputs` attribute with some promotion types. See [Limitations on Usage of `custom_inputs` with Specific Promotion Types](/docs/api/carts/manage-carts#limitations-on-usage-of-custom_inputs-with-specific-promotion-types). To remove promotion from the cart via the promotion code, see [Delete Promotion Code from Cart](/docs/api/carts/delete-a-promotion-via-promotion-code). ### Re-order From a shopper's order history, they can add the items from a previous order into their carts. Shoppers can add items regardless of past order status, such as incomplete or not paid. For more information, see [Orders](/docs/api/carts/orders). :::note - Any requests to add an item to cart return a collection of [cart items](/docs/api/carts/cart-items). - A cart can contain a maximum of 100 unique items. Items include products, custom items, and promotions. - When a shopper creates a cart and re-orders items from an order with properties such as custom attributes, custom discounts, and payment intent ID, these properties will remain unchanged in the original cart. - Custom items do not exist in catalogs, and therefore cannot be reordered. ::: ### Merging Carts A shopper can have multiple carts, and the system may automatically merge items from an anonymous cart into the shopper's registered cart when they sign in. For example, if a shopper has an existing cart with items `A`, `B` and `C`, and later adds items `D` and `E` while not signed in, the system can merge these carts when the shopper signs in. After the carts merge, the cart contains items `A`, `B`, `C`, `D` and `E`. If any items are duplicated from the anonymous cart to the registered cart, their quantities are incremented accordingly. For example, if a shopper's existing cart with items `A`, `B` and `C`, and they later add two more `A` items and one `B` item while not signed in, the system will merge the carts when the shopper signs in. The existing cart will now contain three `A` items, two `B` items, and one `C` item. :::note When the system merges items from one cart into another cart, properties such as custom attributes, custom discounts, and payment intent ID will remain unchanged in the original cart. ::: ### Best Practices We recommend to include a unique `sku` code within the request body while adding custom items to carts. If the same `sku` is used for multiple products, they are merged into a single line item. For example, if a cart consists of the following items: - `product-1` with quantity 1 and sku code as `sku-1` - `product-2` with quantity 1 and sku code as `sku-1` - `product-3` with quantity 1 and sku code as `sku-2`. The following response is returned where it combines all products with the same sku codes into a single line item, while products with a unique sku codes are represented as separate items: ```json { "data": [ { "id": "c58760f4-8889-4719-b34d-be1f1d11ae59", "type": "custom_item", "name": "product-1", "description": "My first custom item!", "sku": "sku-1", "slug": "", "image": { "mime_type": "", "file_name": "", "href": "" }, "quantity": 2, "manage_stock": false, "unit_price": { "amount": 20000, "currency": "USD", "includes_tax": true }, "value": { "amount": 40000, "currency": "USD", "includes_tax": true }, "links": {}, "meta": { "display_price": { "with_tax": { "unit": { "amount": 20000, "currency": "USD", "formatted": "$200.00" }, "value": { "amount": 40000, "currency": "USD", "formatted": "$400.00" } }, "without_tax": { "unit": { "amount": 20000, "currency": "USD", "formatted": "$200.00" }, "value": { "amount": 40000, "currency": "USD", "formatted": "$400.00" } }, "tax": { "unit": { "amount": 0, "currency": "USD", "formatted": "$0.00" }, "value": { "amount": 0, "currency": "USD", "formatted": "$0.00" } }, "discount": { "unit": { "amount": 0, "currency": "USD", "formatted": "$0.00" }, "value": { "amount": 0, "currency": "USD", "formatted": "$0.00" } }, "without_discount": { "unit": { "amount": 20000, "currency": "USD", "formatted": "$200.00" }, "value": { "amount": 40000, "currency": "USD", "formatted": "$400.00" } } }, "timestamps": { "created_at": "2023-05-02T16:28:11Z", "updated_at": "2023-05-02T16:28:18Z" } } ] ``` Request --- ## Orders An Order is created through the [checkout](/docs/api/carts/checkout) endpoint within the Carts API. An order is created after a customer checks out their cart. On creation, the order is marked unpaid. The customer is prompted for a shipping address, a billing address, and a payment method. After the order is successfully paid, you can trigger an inventory process and a shipping process. You can keep a history of orders associated with the customer account. ### Reorder A re-order is when a shopper copies items from a previous order from their order history into a cart of their choice. If a shopper re-orders to an empty cart, the same quantities as the past order are applied. If the shopper re-orders to an existing cart, and orders the same item, the quantity increases. If an item is out of stock, the item is not added to the cart, and the shopper sees an insufficient stock error. The tax for the items in a re-order is not applied. For more information, see [Tax Items](/docs/api/carts/tax-items). ```mdx-code-block import DocCardList from '@theme/DocCardList'; import {useCurrentSidebarCategory} from '@docusaurus/theme-common'; ``` --- ## Payments import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Depending on the payment gateway, you may have access to different transaction types such as capturing funds immediately or authorizing them for later. For more information, see [Payments](/docs/api/carts/payments). The following types of payment methods are available depending on the payment gateway: - `purchase`: This is the simplest method. The gateway attempts to charge the customer immediately. - `authorize`: This method authorizes a payment so that funds can be captured later, for example, when an item is dispatched or restocked. - `purchase_setup`: This method prepares the system for a purchase by verifying payment details without actually charging the customer. For example, a customer adds items to their cart and proceeds to checkout. Before finalizing the purchase, the system runs `purchase_setup` to confirm all payment details, but no funds are transferred until the customer confirms the order. - `authorize_setup`: This method prepares the system for an authorization-only transaction. This process holds the necessary funds but does not transfer them, ensuring that the customer has sufficient balance for the transaction. It sets up the conditions for a future capture of the authorized funds. For example, a customer places a pre-order for a product that will ship in two weeks. The merchant uses `authorize_setup` to prepare for the payment authorization. This holds the customer's funds to ensure they can cover the purchase but waits to capture the payment until the product ships. This ensures that payment is secured but not collected prematurely. :::note Split payments can be performed using any methods for any gateway. - You can partially pay funds using `purchase` method. The gateway attempts to charge the customer immediately, and the payment status for an order will show `partially_paid` - You can partially pay for an order using `authorize` method where the order will be marked as `partially_authorized`. The transaction must be completed for the order status to be `partially_authorized`. - A `purchase_setup` method allows verification of payment details for partial payments without transferring funds until the customer confirms the full order. - An `authorize_setup` method can be used to hold a partial amount of the total funds, ensuring the customer has enough balance for a future capture. Until a payment is made neither `purchase_setup` nor `authorize_setup` affects the payment statuses, and the order remains unpaid. For more information about order and payment statuses for split payments, see [Split payments](/docs/api/payments/payment-gateways-introduction#split-payments). ::: Request --- ## Payments(Carts) When you [checkout](/docs/api/carts/checkout) a [cart](/docs/api/carts/cart-management), an unpaid [order](/docs/api/carts/orders) is returned. You can process the payment for the order though a payment gateway. :::note - You need to configure and enable a payment gateway before you can accept payments for orders. - Configure your store to use [Manual Gateway](/docs/api/payments/update-manual-gateway) to process payments if the order total is zero or the payment is through non-supported payment providers. - There are a number of actions that happen to your inventory when checking out and paying for an order. For more information, see [Inventory](/docs/api/pxm/inventory/inventories-introduction). - We recommend to wait until the payment confirmation process is fully completed before proceeding with any additional updates to the order. Making simultaneous updates to the same entity immediately after payment confirmation can lead to a race condition. To learn more information on handling parallel calls to API objects, see [Parallel Calls to API Objects](/guides/Getting-Started/api-contract#parallel-calls-to-api-objects). ::: ### Payment Methods Depending on the chosen gateway, you may or may not have access to capture funds immediately or authorize for later payment. To make a partial payment in Postman through any payment gateway, specify the desired payment amount in the amount field within the request body. To learn about Split Payments, see the [Split Payments](/docs/api/payments/payment-gateways-introduction#split-payments) section. #### Purchase The simplest method is purchase. The gateway attempts to charge the customer immediately, and the result of the attempt is returned. You can partially pay funds using purchase method. The gateway attempts to charge the customer immediately, and the payment status for an order shows `partially_paid`. When you Get an order, you can see the following fields in the `meta` object: - `balance_owing`: Specifies the outstanding funds required to complete an order. It considers all complete or pending transactions, including authorized, paid, and captured transactions. (`balance_owing` = order total - `authorized` amount - `paid` amount). - `paid`: Specifies the total amount of purchased or captured transactions. - `authorized`: Specifies the total amount of completed or pending authorized transactions for an order. #### Authorize You can `authorize` a payment so funds can later be captured when an item is dispatched or restocked. You can partially pay for an order using `authorize` payment method so that the order is `partially_authorized`. The transaction must be complete for the order status to be `partially_authorized`. For more information about order and payment statuses for split payments, see [Split Payments](/docs/api/payments/payment-gateways-introduction#split-payments). #### Capture After authorizing a transaction, you have to capture the authorized funds. :::note We recommend capturing payments several hours to days after the authorization to mitigate risks of fraud and chargebacks. When you sell digital goods that are delivered immediately, we recommend using a single purchase call instead of separate authorize and capture calls. ::: After the payment is `partially_authorized`, you must `capture` the authorized transaction later. Once you capture the authorized transactions, the order payment status will change to `partially_paid`. #### Refunds You can use either the Refund through Composable Commerce or use the Mark as Refunded capability, or a combination of both capabilities. For more information about refund for split payments, see [Refund a Payment](/docs/api/carts/refund-a-transaction). #### Refund through Composable Commerce You can start a full or partial refund to a supported payment provider directly from Commerce Manager or the API. When you start the refund process, the refund request is sent to the payment gateway. You no longer have to log on to your payment gateway's console to process the refund. When you process a refund, use the refund endpoint to pass the refund amount. If you don't pass an amount, the refund is processed as Mark as refunded. For more information, see the Mark as Refunded section. Each time a partial refund is triggered, the transaction.updated event is generated and updated with refunded.amount. The `order.updated` event is also triggered. The `order.refunded` event generates when the full amount is refunded. #### Mark as Refunded You can use your payment gateway's console to process a refund. Process the refund first in the payment gateway and then use the **Mark as Refunded** capability in Composable Commerce to complete the process. When an order is **Marked as refunded**, the payment status `order.payment.status` is set to `refunded`. In this case, the `order.updated`, `transaction.updated` and `order.refunded` events are generated. ```mdx-code-block import DocCardList from '@theme/DocCardList'; import {useCurrentSidebarCategory} from '@docusaurus/theme-common'; ``` --- ## Update a shipping group for an order import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Update a shipping group for an order Request --- ## Update Cart Settings by Store ID import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; You can modify the cart expiry settings to set it to any number of days up to 365. Any existing carts default to the expiry of 7 days. To update cart settings in Commerce Manager, see [Updating Cart setting](/docs/commerce-manager/settings/general-settings#updating-cart-settings). With update cart settings endpoint, you can: - Enable or disable custom discounts by setting the `custom_discounts_enabled` field to `true`. This allows you to activate your custom discounts from external services. By default, this setting is determined by the cart settings configured for the store. - Enable or disable the use of rule promotions within the cart. You can apply this setting either at the store level using the update cart setting endpoint or individually to a specific cart using the [update a cart](/docs/api/carts/update-a-cart) endpoint. - Enable or disable deferred inventory checks by setting `defer_inventory_check` to `true`. When set, stock levels are not verified for products in a cart until checkout. - Control whether admins can see all carts or only shopper-associated carts by setting `show_all_carts` to `true` or `false`. - Enable or disable location-based item separation by setting `separate_items_by_location` to `true`. When enabled, cart items with the same SKU but different locations are kept as separate line items instead of being merged. :::note Custom discounts and rule promotions can both be enabled for a store at the same time, for example, while transitioning from one promotion system to the other. However, an individual cart can only contain one type of discount at a time. A cart that contains custom discounts rejects Elastic Path promotions, and a cart that contains Elastic Path promotions rejects custom discounts, until the existing discounts are removed. ::: Request --- ## Update Cart Settings import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; You can modify the cart expiry settings to set it to any number of days up to 365. Any existing carts default to the expiry of 7 days. To update cart settings in Commerce Manager, see [Updating Cart setting](/docs/commerce-manager/settings/general-settings#updating-cart-settings). With update cart settings endpoint, you can: - Enable or disable custom discounts by setting the `custom_discounts_enabled` field to `true`. This allows you to activate your custom discounts from external services. By default, this setting is determined by the cart settings configured for the store. - Enable or disable the use of rule promotions within the cart. You can apply this setting either at the store level using the update cart setting endpoint or individually to a specific cart using the [update a cart](/docs/api/carts/update-a-cart) endpoint. - Enable or disable deferred inventory checks by setting `defer_inventory_check` to `true`. When set, stock levels are not verified for products in a cart until checkout. - Control whether admins can see all carts or only shopper-associated carts by setting `show_all_carts` to `true` or `false`. - Enable or disable location-based item separation by setting `separate_items_by_location` to `true`. When enabled, cart items with the same SKU but different locations are kept as separate line items instead of being merged. :::note Custom discounts and rule promotions can both be enabled for a store at the same time, for example, while transitioning from one promotion system to the other. However, an individual cart can only contain one type of discount at a time. A cart that contains custom discounts rejects Elastic Path promotions, and a cart that contains Elastic Path promotions rejects custom discounts, until the existing discounts are removed. ::: Request --- ## Refund a Transaction import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; There are two ways to refund; through your payment gateway and mark it refunded in Commerce Manager, or directly through Commerce Manager or API. * Mark as Refunded: You can manually mark a transaction as refunded. Before you can mark the order as refunded, you need to handle the actual refund on your side with your payment provider. Mark as Refunded is a full refund made to the transaction. * Refund through Composable Commerce: You can process a full or partial refund to a supported payment provider directly from Commerce Manager or API by providing the refund amount. When you start the refund process, the request is directly sent to the payment gateway. :::caution If you use manual gateway for partial or full refund, you need to handle the actual refund on your side with your payment provider. ::: Request --- ## Tax Items Taxes differ by country and can differ within the country by region, state, or province. Each jurisdiction has a unique tax code and rate. If your store serves many jurisdictions, integrate a third-party tax generator to manage taxes. If your store serves a few jurisdictions, you can use the API to define the tax codes and rates in Composable Commerce. Taxes are calculated after all promotional discounts have been applied. When calculating taxes on a cart or order, you can choose from the following methods for calculating taxes: - Simple calculation method: Taxes are calculated at the unit level and are rounded to the nearest penny for the unit. - Line calculation method: Default. Taxes are calculated at the line level and are rounded to the nearest penny for the line. For more information about calculation methods, see [Calculate cart and order totals](/guides/How-To/Carts/calculate-totals). Tax values can be either `rate` or `amount`. - `rate` - Represents the tax as a percentage in decimal form. - `amount` - Represents a tax amount. :::note Tax items can be added and removed using [client_credentials access tokens](/docs/api/authentication/create-an-access-token). Only administrators with `client-credentials` access tokens are able to manage tax items. ::: ```mdx-code-block import DocCardList from '@theme/DocCardList'; import {useCurrentSidebarCategory} from '@docusaurus/theme-common'; ``` --- ## Update a Cart Item import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; You can easily update a cart item. A successful update returns the cart items. Request --- ## Update a Cart import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Updates cart properties for the specified cartID. You can update a cart to specify custom discounts. You can enable custom discounts when the `discount_settings.custom_discounts_enabled` field is set to `true`. Default is set from cart discount settings for the store. See [Cart Settings](/docs/api/carts/put-v-2-settings-cart). You can also create a cart when inventory checks are not performed until checkout by setting the `inventory_settings.defer_inventory_check` field to `true`. Again the default is set from cart discount settings for the store. See [Update Cart Settings](/docs/api/carts/put-v-2-settings-cart). Request --- ## Update a Tax Item import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Use this endpoint to update a tax item. To change tax value from `rate` to `amount`, set `rate` to `null`, then set `amount` value and vice versa. Request 0.125). You must specify either `rate` or `amount`, but not both.\n","type":"number"},"amount":{"description":"The tax as an absolute amount in the smallest currency unit (e.g., $10 -> 1000). You must specify either `rate` or `amount`, but not both.\n","type":"number"},"type":{"description":"The type of object being returned. Use `tax_item`.","type":"string","const":"tax_item"},"id":{"description":"The unique identifier for this tax item.","type":"string","format":"uuid","readOnly":true}},"title":"CartsItemsTaxesCommon"},{"type":"object","required":["rate"],"properties":{"rate":{"description":"The tax rate as a decimal (12.5% -> 0.125). Required when using rate-based taxation.\n","type":"number","examples":[0.2]},"amount":{"description":"The tax as an absolute amount. Not allowed when rate is specified.\n","type":"number","examples":[1000]}},"not":{"type":"object","required":["amount"],"properties":{"amount":{"type":"number"}}}}]},{"title":"Tax Object (With Amount)","allOf":[{"type":"object","required":["type"],"properties":{"code":{"description":"A unique tax code in this jurisdiction.","type":"string"},"jurisdiction":{"description":"The relevant tax jurisdiction.","type":"string"},"name":{"description":"The name of the tax item.","type":"string"},"rate":{"description":"The tax rate as a decimal (12.5% -> 0.125). You must specify either `rate` or `amount`, but not both.\n","type":"number"},"amount":{"description":"The tax as an absolute amount in the smallest currency unit (e.g., $10 -> 1000). You must specify either `rate` or `amount`, but not both.\n","type":"number"},"type":{"description":"The type of object being returned. Use `tax_item`.","type":"string","const":"tax_item"},"id":{"description":"The unique identifier for this tax item.","type":"string","format":"uuid","readOnly":true}},"title":"CartsItemsTaxesCommon"},{"type":"object","required":["amount"],"properties":{"amount":{"description":"The tax as an absolute amount in the smallest currency unit (e.g., $10 -> 1000). Required when using amount-based taxation.\n","type":"number","examples":[1000]},"rate":{"description":"The tax rate as a decimal. Not allowed when amount is specified.\n","type":"number","examples":[0.2]}},"not":{"type":"object","required":["rate"],"properties":{"rate":{"type":"number"}}}}]}],"examples":[{"type":"tax_item","code":"VAT","jurisdiction":"UK","name":"Value Added Tax","rate":0.2},{"type":"tax_item","code":"EXCISE","jurisdiction":"US","name":"Excise Tax","amount":500}]}},"required":["data"],"title":"CartItemTaxesEntityResponse"},"examples":{"updateRateTaxItem":{"summary":"Update a tax item using rate","value":{"data":{"type":"tax_item","code":"VAT","jurisdiction":"UK","name":"Value Added Tax","rate":0.15}}},"updateAmountTaxItem":{"summary":"Update a tax item using amount","value":{"data":{"type":"tax_item","code":"GST","jurisdiction":"AU","name":"Goods and Services Tax","amount":1500}}}}}},"required":false}} > 0.125). You must specify either `rate` or `amount`, but not both.\n","type":"number"},"amount":{"description":"The tax as an absolute amount in the smallest currency unit (e.g., $10 -> 1000). You must specify either `rate` or `amount`, but not both.\n","type":"number"},"type":{"description":"The type of object being returned. Use `tax_item`.","type":"string","const":"tax_item"},"id":{"description":"The unique identifier for this tax item.","type":"string","format":"uuid","readOnly":true}},"title":"CartsItemsTaxesCommon"},{"type":"object","required":["rate"],"properties":{"rate":{"description":"The tax rate as a decimal (12.5% -> 0.125). Required when using rate-based taxation.\n","type":"number","examples":[0.2]},"amount":{"description":"The tax as an absolute amount. Not allowed when rate is specified.\n","type":"number","examples":[1000]}},"not":{"type":"object","required":["amount"],"properties":{"amount":{"type":"number"}}}}]},{"title":"Tax Object (With Amount)","allOf":[{"type":"object","required":["type"],"properties":{"code":{"description":"A unique tax code in this jurisdiction.","type":"string"},"jurisdiction":{"description":"The relevant tax jurisdiction.","type":"string"},"name":{"description":"The name of the tax item.","type":"string"},"rate":{"description":"The tax rate as a decimal (12.5% -> 0.125). You must specify either `rate` or `amount`, but not both.\n","type":"number"},"amount":{"description":"The tax as an absolute amount in the smallest currency unit (e.g., $10 -> 1000). You must specify either `rate` or `amount`, but not both.\n","type":"number"},"type":{"description":"The type of object being returned. Use `tax_item`.","type":"string","const":"tax_item"},"id":{"description":"The unique identifier for this tax item.","type":"string","format":"uuid","readOnly":true}},"title":"CartsItemsTaxesCommon"},{"type":"object","required":["amount"],"properties":{"amount":{"description":"The tax as an absolute amount in the smallest currency unit (e.g., $10 -> 1000). Required when using amount-based taxation.\n","type":"number","examples":[1000]},"rate":{"description":"The tax rate as a decimal. Not allowed when amount is specified.\n","type":"number","examples":[0.2]}},"not":{"type":"object","required":["rate"],"properties":{"rate":{"type":"number"}}}}]}],"examples":[{"type":"tax_item","code":"VAT","jurisdiction":"UK","name":"Value Added Tax","rate":0.2},{"type":"tax_item","code":"EXCISE","jurisdiction":"US","name":"Excise Tax","amount":500}]}},"required":["data"],"title":"CartItemTaxesEntityResponse"},"examples":{"updatedRateTaxItem":{"summary":"Updated tax item (rate)","value":{"data":{"id":"662461ad-ddcb-4dbd-8ed7-ade9aa63b5f9","type":"tax_item","code":"VAT","jurisdiction":"UK","name":"Value Added Tax","rate":0.15}}}}}}}}} > --- ## Update an Order import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; You can only update custom data, `shipping`, `shipping_address`, and status of orders. All other settings in the order object are immutable. This endpoint allows you to: - **Update an order number and external reference**: You can update an existing order that does not have an `order_number` and `external_ref`, modify the `order_number` and `external_ref` values, or remove them by passing an empty value in the `order_number` and `external_ref` fields. - **Cancel an order**: You can cancel an order only if it has not been fulfilled. - **Fulfill an order**: You can fulfill a paid order only. :::caution You can update `shipping`, `shipping_address`, and status of an order only if the order is not fulfilled. You can use the refund API to refund an order only if the payment status is `paid`. Canceling an order does not automatically refund a payment. You must refund the orders manually. ::: :::note - This request is only accessible to client credentials token users with Seller Admin role. - Non client credentials token users cannot access this endpoint. See [Permissions](/docs/authentication/tokens/permissions). - The `order_number` will appear as the invoice number in Authorize.net transactions. ::: Request --- ## Update a Payment Intent on a Cart import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Updates the payment information for a specific payment intent on a cart. Request --- ## Update Custom Discount For Cart Item import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Use this endpoint to update a custom discount in your cart item. Request --- ## Update Custom Discount For Cart import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Use this endpoint to update a custom discount in your cart. Request --- ## Update a shipping group for a cart import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Update a specific shipping group for a cart Request --- ## Update Tax Item on Bundle Component import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Use this endpoint to update a tax item on a specific bundle component (component product) within a cart item. To change tax value from `rate` to `amount`, set `rate` to `null`, then set `amount` value and vice versa. Request 0.125). You must specify either `rate` or `amount`, but not both.\n","type":"number"},"amount":{"description":"The tax as an absolute amount in the smallest currency unit (e.g., $10 -> 1000). You must specify either `rate` or `amount`, but not both.\n","type":"number"},"type":{"description":"The type of object being returned. Use `tax_item`.","type":"string","const":"tax_item"},"id":{"description":"The unique identifier for this tax item.","type":"string","format":"uuid","readOnly":true}},"title":"CartsItemsTaxesCommon"},{"type":"object","required":["rate"],"properties":{"rate":{"description":"The tax rate as a decimal (12.5% -> 0.125). Required when using rate-based taxation.\n","type":"number","examples":[0.2]},"amount":{"description":"The tax as an absolute amount. Not allowed when rate is specified.\n","type":"number","examples":[1000]}},"not":{"type":"object","required":["amount"],"properties":{"amount":{"type":"number"}}}}]},{"title":"Tax Object (With Amount)","allOf":[{"type":"object","required":["type"],"properties":{"code":{"description":"A unique tax code in this jurisdiction.","type":"string"},"jurisdiction":{"description":"The relevant tax jurisdiction.","type":"string"},"name":{"description":"The name of the tax item.","type":"string"},"rate":{"description":"The tax rate as a decimal (12.5% -> 0.125). You must specify either `rate` or `amount`, but not both.\n","type":"number"},"amount":{"description":"The tax as an absolute amount in the smallest currency unit (e.g., $10 -> 1000). You must specify either `rate` or `amount`, but not both.\n","type":"number"},"type":{"description":"The type of object being returned. Use `tax_item`.","type":"string","const":"tax_item"},"id":{"description":"The unique identifier for this tax item.","type":"string","format":"uuid","readOnly":true}},"title":"CartsItemsTaxesCommon"},{"type":"object","required":["amount"],"properties":{"amount":{"description":"The tax as an absolute amount in the smallest currency unit (e.g., $10 -> 1000). Required when using amount-based taxation.\n","type":"number","examples":[1000]},"rate":{"description":"The tax rate as a decimal. Not allowed when amount is specified.\n","type":"number","examples":[0.2]}},"not":{"type":"object","required":["rate"],"properties":{"rate":{"type":"number"}}}}]}],"examples":[{"type":"tax_item","code":"VAT","jurisdiction":"UK","name":"Value Added Tax","rate":0.2},{"type":"tax_item","code":"EXCISE","jurisdiction":"US","name":"Excise Tax","amount":500}]}},"required":["data"],"title":"CartItemTaxesEntityResponse"},"examples":{"updateRateTaxItemComponent":{"summary":"Update a bundle component tax item using rate","value":{"data":{"type":"tax_item","code":"VAT","jurisdiction":"UK","name":"Value Added Tax","rate":0.18}}},"updateAmountTaxItemComponent":{"summary":"Update a bundle component tax item using amount","value":{"data":{"type":"tax_item","code":"GST","jurisdiction":"AU","name":"Goods and Services Tax","amount":1200}}}}}},"required":false}} > 0.125). You must specify either `rate` or `amount`, but not both.\n","type":"number"},"amount":{"description":"The tax as an absolute amount in the smallest currency unit (e.g., $10 -> 1000). You must specify either `rate` or `amount`, but not both.\n","type":"number"},"type":{"description":"The type of object being returned. Use `tax_item`.","type":"string","const":"tax_item"},"id":{"description":"The unique identifier for this tax item.","type":"string","format":"uuid","readOnly":true}},"title":"CartsItemsTaxesCommon"},{"type":"object","required":["rate"],"properties":{"rate":{"description":"The tax rate as a decimal (12.5% -> 0.125). Required when using rate-based taxation.\n","type":"number","examples":[0.2]},"amount":{"description":"The tax as an absolute amount. Not allowed when rate is specified.\n","type":"number","examples":[1000]}},"not":{"type":"object","required":["amount"],"properties":{"amount":{"type":"number"}}}}]},{"title":"Tax Object (With Amount)","allOf":[{"type":"object","required":["type"],"properties":{"code":{"description":"A unique tax code in this jurisdiction.","type":"string"},"jurisdiction":{"description":"The relevant tax jurisdiction.","type":"string"},"name":{"description":"The name of the tax item.","type":"string"},"rate":{"description":"The tax rate as a decimal (12.5% -> 0.125). You must specify either `rate` or `amount`, but not both.\n","type":"number"},"amount":{"description":"The tax as an absolute amount in the smallest currency unit (e.g., $10 -> 1000). You must specify either `rate` or `amount`, but not both.\n","type":"number"},"type":{"description":"The type of object being returned. Use `tax_item`.","type":"string","const":"tax_item"},"id":{"description":"The unique identifier for this tax item.","type":"string","format":"uuid","readOnly":true}},"title":"CartsItemsTaxesCommon"},{"type":"object","required":["amount"],"properties":{"amount":{"description":"The tax as an absolute amount in the smallest currency unit (e.g., $10 -> 1000). Required when using amount-based taxation.\n","type":"number","examples":[1000]},"rate":{"description":"The tax rate as a decimal. Not allowed when amount is specified.\n","type":"number","examples":[0.2]}},"not":{"type":"object","required":["rate"],"properties":{"rate":{"type":"number"}}}}]}],"examples":[{"type":"tax_item","code":"VAT","jurisdiction":"UK","name":"Value Added Tax","rate":0.2},{"type":"tax_item","code":"EXCISE","jurisdiction":"US","name":"Excise Tax","amount":500}]}},"required":["data"],"title":"CartItemTaxesEntityResponse"},"examples":{"componentUpdatedAmountTaxItem":{"summary":"Updated bundle component tax item (amount)","value":{"data":{"id":"7aa2ddad-2c5b-4d9b-9ce9-3e8cff778a10","type":"tax_item","code":"GST","jurisdiction":"AU","name":"Goods and Services Tax","amount":1200}}}}}}}}} > --- ## Commerce Extensions Introduction import ApiLogo from "@theme/ApiLogo"; import Heading from "@theme/Heading"; import SchemaTabs from "@theme/SchemaTabs"; import TabItem from "@theme/TabItem"; import Export from "@theme/ApiExplorer/Export"; Commerce Extensions is a Database as a Service (DBaaS) that allows for the creation of Custom APIs and extend the capabilities of Commerce. With Custom APIs, you can efficiently manage large data sets while benefiting from both simple and complex multidimensional filtering options. Combining Custom APIs with [Composer](/docs/composer/index) enables you to deploy custom behaviors and integrations, allowing you to implement capabilities unique to your business without having to build and host that functionality from scratch. Commerce Extensions is the next generation of Flows. Flows are not going anywhere, but going forward as we add new features, Commerce Extensions will eventually provide all the capabilities and more that Flows does. We recommend using Custom APIs for any of your new use cases. Security Scheme Type: http HTTP Authorization Scheme: bearer Contact Elastic Path: [support@elasticpath.com](mailto:support@elasticpath.com) URL: [https://www.elasticpath.com](https://www.elasticpath.com) License MIT --- ## Create a Custom API Entry import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Create a Custom API Entry Request --- ## Create a Custom API import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Create a Custom API Request `.\n","pattern":"^[a-z0-9_-]{1,63}$"},"api_type":{"type":"string","description":"Specifies a unique API type for this Custom API. Entries for this API will use this value for their `type` field. This field must be suffixed with `_ext` to distinguish it from built in APIs.\n","pattern":"^[a-z0-9_]{1,59}_ext$"},"allow_upserts":{"type":"boolean","description":"Controls whether upsert operations are allowed for Custom API Entries via the `PUT` method. When set to `true`, it allows the creation of new Custom API Entries using `PUT` if the record doesn't exist, and updates the existing record if it does. When `false`, `PUT` requests can only update existing entries.\n","default":false},"presentation":{"type":"object","description":"Optional presentation options for the Custom API.","properties":{"page":{"type":["string","null"],"description":"The page where this Custom API should be presented. The available values depend on the deployment and may change."},"section":{"type":["string","null"],"description":"The section within the page. Can only be set when `page` is also set.","maxLength":64}}},"relationships":{"type":"object","properties":{"parent_apis":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier for the related Custom API. When the `type` of an object is set to `api_location` then `id` must be `/v2/extensions`.\nWhen the `type` of an object is set to `custom_api`, then `id` must be that of a Custom API that results in a relationship that does not have a depth exceeding 2 and does not result in a cycle.\n","example":"652e39d8-d613-493e-8c20-fef99ad6327a"},"type":{"type":"string","description":"Specifies the type of parent relationship, can be `custom_api` or `api_location`.","enum":["custom_api","api_location"]}}}}}}},"title":"CustomAPIRelationships"}}}}},"examples":{"Create Example":{"summary":"Create a Custom API","value":{"data":{"type":"custom_api","name":"Wishlists","description":"Specifies the description for this Custom API.","slug":"wishlists","api_type":"wishlist_ext","relationships":{"parent_apis":{"data":[{"id":"652e39d8-d613-493e-8c20-fef99ad6327a","type":"custom_api"}]}}}}}}}}}} > `.\n","pattern":"^[a-z0-9_-]{1,63}$"},"api_type":{"type":"string","description":"Specifies a unique API type for this Custom API. Entries for this API will use this value for their `type` field. This field must be suffixed with `_ext` to distinguish it from built in APIs.\n","pattern":"^[a-z0-9_]{1,59}_ext$"},"allow_upserts":{"type":"boolean","description":"Controls whether upsert operations are allowed for Custom API Entries via the `PUT` method. When set to `true`, it allows the creation of new Custom API Entries using `PUT` if the record doesn't exist, and updates the existing record if it does. When `false`, `PUT` requests can only update existing entries.\n","default":false},"presentation":{"type":"object","description":"Optional presentation options for the Custom API.","properties":{"page":{"type":["string","null"],"description":"The page where this Custom API should be presented. The available values depend on the deployment and may change."},"section":{"type":["string","null"],"description":"The section within the page. Can only be set when `page` is also set."}}},"links":{"type":"object","properties":{"self":{"description":"Specifies the URI of the Custom API.","example":"/v2/settings/extensions/custom-apis/3fa85f64-5717-4562-b3fc-2c963f66afa6","type":["string","null"],"format":"uri","title":"LinkURI"}}},"meta":{"type":"object","properties":{"timestamps":{"type":"object","properties":{"created_at":{"type":"string","description":"Specifies the date the entity is created.","example":"2017-01-10T11:41:19.244Z"},"updated_at":{"type":"string","description":"Specifies the date the entity is last updated.","example":"2017-01-10T11:41:19.244Z"}},"title":"Timestamps"}},"title":"Meta"},"relationships":{"type":"object","properties":{"parent_apis":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier for the related Custom API. When the `type` of an object is set to `api_location` then `id` must be `/v2/extensions`.\nWhen the `type` of an object is set to `custom_api`, then `id` must be that of a Custom API that results in a relationship that does not have a depth exceeding 2 and does not result in a cycle.\n","example":"652e39d8-d613-493e-8c20-fef99ad6327a"},"type":{"type":"string","description":"Specifies the type of parent relationship, can be `custom_api` or `api_location`.","enum":["custom_api","api_location"]}}}}}}},"title":"CustomAPIRelationships"}},"title":"CustomAPI"}}}}}},"400":{"description":"Bad request. The request failed validation.","content":{"application/json":{"schema":{"required":["errors"],"properties":{"errors":{"type":"array","items":{"type":"object","required":["status","title"],"properties":{"status":{"type":"string","description":"The HTTP response code of the error.","format":"string","examples":["400"]},"title":{"type":"string","description":"A brief summary of the error.","examples":["Bad Request"]},"detail":{"type":"string","description":"Optional additional detail about the error.","examples":["The field 'name' is required"]}}}}},"title":"Errors"},"examples":{"Missing Name":{"summary":"Required field missing","value":"{\n \"errors\": [\n {\n \"title\": \"Bad Request\",\n \"status\": \"400\",\n \"detail\": \"The field 'name' is required.\"\n }\n ]\n}\n"}}}}},"409":{"description":"Unable to perform the operation at this time.","content":{"application/json":{"schema":{"required":["errors"],"properties":{"errors":{"type":"array","items":{"type":"object","required":["status","title"],"properties":{"status":{"type":"string","description":"The HTTP response code of the error.","format":"string","examples":["400"]},"title":{"type":"string","description":"A brief summary of the error.","examples":["Bad Request"]},"detail":{"type":"string","description":"Optional additional detail about the error.","examples":["The field 'name' is required"]}}}}},"title":"Errors"},"examples":{"Duplicate Custom API":{"summary":"Duplicate Custom API","value":"{\n \"errors\": [\n {\n \"title\": \"Conflict\",\n \"status\": \"409\",\n \"detail\": \"custom_api with the given api_type already exists\"\n }\n ]\n}\n"},"Duplicate Custom Field":{"summary":"Duplicate Custom Field","value":"{\n \"errors\": [\n {\n \"title\": \"Conflict\",\n \"status\": \"409\",\n \"detail\": \"custom_field with the given slug already exists\"\n }\n ]\n}\n"}}}}},"500":{"description":"Internal server error. There was a system failure in the platform.","content":{"application/json":{"schema":{"required":["errors"],"properties":{"errors":{"type":"array","items":{"type":"object","required":["status","title"],"properties":{"status":{"type":"string","description":"The HTTP response code of the error.","format":"string","examples":["400"]},"title":{"type":"string","description":"A brief summary of the error.","examples":["Bad Request"]},"detail":{"type":"string","description":"Optional additional detail about the error.","examples":["The field 'name' is required"]}}}}},"title":"Errors"},"examples":{"Internal Server Error":{"summary":"Internal server error","value":"{\n \"errors\": [\n {\n \"title\": \"Internal Server Error\",\n \"status\": \"500\",\n \"detail\": \"there was a problem processing your request\"\n }\n ]\n}\n"}}}}}}} > --- ## Create a Custom Field import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Create a Custom Field Request --- ## Custom APIs Custom APIs allow you to extend the capabilities of Commerce. With Custom APIs, you can efficiently manage large data sets while benefiting from both simple and complex multidimensional filtering options. Combining Custom APIs with [Composer](/docs/composer/index) enables you to deploy custom behaviors and integrations, allowing you to implement capabilities unique to your business without having to build and host that functionality from scratch. A Custom API is composed of one or more [Custom Fields](/docs/api/commerce-extensions/custom-fields) and allows you to create [Entries](/docs/api/commerce-extensions/custom-api-entries). In database terms, a Custom API can be thought of as a table, with fields representing the columns of the table, and entries serving as the database records. ## Custom APIs vs Non-Core Flows Custom APIs are the next generation of Non-Core Flows. Here is a comparison of current features of Non-Core Flows and Custom APIs. This will be updated as we release more capabilities. | Feature | Non-Core Flows | Commerce Extensions | |---------------------------------------------------------------------------------------------------------------------------|----------------|----------------------------------------------------------------| | Build new APIs | ✅ | ✅ | | Access Level | Implicit | [Customizable](/docs/api/permissions/custom-api-role-policies) | | [Filtering](/docs/api/commerce-extensions/list-custom-api-entries#filtering) | ⛔️ | ✅ | | [Sorting](/docs/api/commerce-extensions/list-custom-api-entries#sorting) | ⛔️ | ✅ | | [Events](/docs/api/commerce-extensions/custom-api-entries#events) | ⛔️ | ✅ | | [Conditional Updates](/guides/How-To/commerce-extensions/create-a-multilocation-inventories-resource#conditional-updates) | ⛔️ | ✅ | The [Custom Fields Overview](/docs/api/commerce-extensions/custom-fields) lists the comparison of different types and validation available in Custom APIs vs Non-Core Flows. ```mdx-code-block import DocCardList from '@theme/DocCardList'; import {useCurrentSidebarCategory} from '@docusaurus/theme-common'; ``` --- ## Custom API Entries A **Custom API Entry** is a specific instance of a resource, such as a single wishlist in a Custom API for wishlists. Custom API Entries can be accessed in two different ways, via the **extension** endpoint, or the **settings** endpoint: * Extension Endpoint: `/v2/extensions/{custom-api-slug}` - This is the primary endpoint created for use. Most clients should use this endpoint as it adheres to the semantics of the configuration. Retrieve the [OpenAPI Specifications](/docs/api/commerce-extensions/get-open-api-specification) to learn how to interact with this endpoint. * Settings Endpoint: `/v2/settings/extensions/custom-apis/{custom-api-id}/entries/` - This endpoint should only be used in cases where you want to interact with your Custom APIs in a generic way in an admin capacity. Currently, the distinction between these endpoints is minimal. The extension endpoint uses a slug in the URL path, and the settings endpoint uses an ID. For most use cases involving the new Custom API, we recommend using the extension endpoint. Conceptually, the settings endpoint is analogous to reflection in most programming languages. You use it when you want to operate in a generic way. For example, we used the settings endpoint to build Commerce Manager. Another example is if you need to import and export various types of data from CSV files. Instead of writing multiple scripts for different extension endpoints, you can write one script that operates on the settings endpoint. ## Events You can integrate Commerce Extensions with your external systems by observing the appropriate events. For more information, see [Integrations](/docs/api/integrations/integrations-introduction). Given you have a Custom API with `api_type` of `wishlist_ext` and you want to perform additional processing when an action is taken, like when a wishlist is created: ```bash curl -X POST https://useast.api.elasticpath.com/v2/extensions/wishlists \ -H "Authorization: Bearer XXXX" \ -H "Content-Type: application/json" \ -d $ { "data": { "type": "wishlist_ext", "name": "My Wishlist", "items_count": 0, "keep_purchased": false } } ``` When you [create an integration](/docs/api/integrations/create-integration) with `wishlist_ext.created` in `observes` field. Then the configured `webhook` or `aws_sqs` will receive the appropriate message. You can configure integrations to observe the following events for your Custom API Entries: * Created * Updated * Deleted ```mdx-code-block import DocCardList from '@theme/DocCardList'; import {useCurrentSidebarCategory} from '@docusaurus/theme-common'; ``` --- ## Custom Fields A Custom Field represents a single field of data (for example a Product Rating). A Custom API is composed of one or more Custom Fields. Here is a comparison of different types and validation available in Custom APIs vs Non-Core Flows. | Feature | Non-Core Flows | Commerce Extensions | |-----------------------------------------------|----------------|--------------------------------------------| | Data Type: String | ✅ | ✅ | | Data Type: Integer | ✅ | ✅ | | Data Type: Float | ✅ | ✅ | | Data Type: Boolean | ✅ | ✅ | | Data Type: List | ⛔ | ✅ | | Data Type: Any | ⛔ | ✅ | | Data Type: Date & Time | ✅ | ✅ Replaced by Regex Validation (See Below) | | Data Type: One To Many | ✅ | Planned | | Validation: Regular Expression | ⛔️ | ✅ | | Validation: Slug/Email | ✅ | ✅ Replaced by Regex Validation (See Below) | | Validation: Min/Max Value | ✅ | ✅ | | Validation: Enum(String) | ✅ | ✅ Replaced by Regex validation (See Below) | | Validation: Enum(Float/Integer) | ✅ | ⛔️ | | Validation: Allow null values | ⛔ | ✅ | | Validation: Unique(String) | ⛔ | ✅ | | Validation: Unique Case Insensitivity(String) | ⛔ | ✅ | | Validation: Immutable | ⛔ | ✅ | ## Validation When [creating](/docs/api/commerce-extensions/create-a-custom-field#request) or [updating](/docs/api/commerce-extensions/update-a-custom-field#request) a Custom Field, `validation` can be used to limit the values that may be stored in the corresponding Custom API Entry. :::note All validation changes, such as those to `allow_null_values` and any type specific rules, apply to new entries only. Existing Custom API Entry records are unaffected until updated. ::: ### Integer Validation - `min_value`: Specifies the minimum whole number that can be stored. If set, it must be less than `max_value`. - `max_value`: Specifies the maximum whole number that can be stored. If set, it must be greater than `min_value`. sample integer validation object: ```json { "validation": { "integer": { "min_value": 0, "max_value": 32 } } } ``` Even if no validation is set, field_type `integer` only supports values between -2^53+1 and 2^53+1. This is because the JSON format doesn't guarantee that values outside this range are portable ([Source](https://datatracker.ietf.org/doc/html/rfc7159#section-6)). ### Float Validation - `min_value`: Specifies the minimum number that can be stored. If set, it must be less than `max_value`. - `max_value`: Specifies the maximum number that can be stored. If set, it must be greater than `min_value`. sample float validation object: ```json { "validation": { "float": { "min_value": 0.01, "max_value": 32.01 } } } ``` The `float` field_type cannot accurately represent some numbers and so using very small or large numbers might lose precision. We recommend that API clients use either the `integer` field_type if applicable , or the `string` data type if perfect precision or recall is required. ### String Validation - `min_length`: Specifies the minimum number of characters that can be stored. If set, it must be greater than 0 and less than `max_length`. - `max_length`: Specifies the maximum number of characters that can be stored. If set, it must be greater than 0 and `min_length`. - `regex`: An [RE2](https://github.com/google/re2/wiki/Syntax) regular expression used to restrict the specific characters that can be stored. It must be less than 1024 characters. - `unique`: Specifies whether the field must have unique constraint or not. It must be `yes` or `no`. - `unique_case_insensitivity`: Applies when `unique` is set to `yes`. It controls whether values with different cases (for example, `ABC` and `abc`) should conflict. It must be `true` or `false`. sample string validation object: ```json { "validation": { "string": { "min_length": 0, "max_length": 64, "regex": "^.+\\.(jpg|jpeg|png|gif|pdf)$", "unique": "yes" "unique_case_insensitivity": true } } } ``` Even if no validation is set, field_type `string` only supports values that are up to `65535` characters long. #### Date & Time Values With Regular Expressions While Commerce Extensions does not have a native date or time type, you can none-the-less use these values in Commerce Extensions, by using the `string` field type and `regex` validation. To ensure that ordering is handled properly you should follow the guidance in [RFC 3339 - Section 5.1 Ordering](https://www.rfc-editor.org/rfc/rfc3339.html#section-5.1), namely store the fields in order of least to most precise, and in the same timezone, this will ensure that comparison operators (e.g., `gt`) and sorting, work as expected, for example the following regex will force all values to be in seconds in UTC: `^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z$` One thing to keep in mind is that some libraries, especially when dealing with sub-seconds might only display them if they are non-zero, and you will want to ensure that they are fully padded to the same length. #### Enum Values with Regular Expressions You can ensure that only some values are allowed using the regular expression `^(alpha|bravo|charlie)$`. #### Slug Values with Regular Expressions Slugs can be replaced with the regular expression `^[a-z][a-z0-9-]*$`, this will ensure that the field starts with a lower case letter, and then has lower case letters, numbers or hyphens. You can tweak this regular expression as needed to suit your needs. ### Email Validation with Regular Expressions E-mails can be tricky to validate properly, especially because many services _accept_ e-mails that are not valid, and reject e-mail addresses that are technically valid. Additionally, your own capabilities and purposes might inform your decision (e.g., if you support [i18n addresses](https://datatracker.ietf.org/doc/html/rfc6530) or don't then the set of allowed e-mails changes). ### List Validation - `min_length`: Specifies the minimum number of elements that must be in the list. - `max_length`: Specifies the maximum number of elements allowed in the list. The maximum supported value is 1000. - `allowed_type`: Specifies the primitive type that all elements in the list must be. Valid values are `string`, `integer`, `boolean`, `float`, or `any`. The default is `any`, which allows mixed types. This value cannot be changed after the field is created. sample list validation object: ```json { "validation": { "list": { "min_length": 1, "max_length": 100, "allowed_type": "string" } } } ``` ### Any Validation The `any` field type allows storing arbitrary JSON values including objects, arrays, strings, numbers, booleans, and null. When updating an entry, the `any` field value is completely replaced, not merged. Filtering is not supported on `any` fields. sample any validation object: ```json { "validation": { "any": { "allow_null_values": true, "immutable": false } } } ``` ### Null Values All Custom Fields can be configured to restrict the storage of `null` values for that field on a Custom API Entry. By default, this is `true`. sample validation object : ```json { "validation": { "boolean": { "allow_null_values": false, "immutable": false } } } ``` ### Immutable When [creating](/docs/api/commerce-extensions/create-a-custom-field#request) a Custom Field, it can be configured to be `immutable`. When set to true, the value of this field can be specified only during POST requests and cannot be modified during PUT requests. By default, this is `false`. sample validation object : ```json { "validation": { "boolean": { "immutable": false } } } ``` ## Presentation When [creating](/docs/api/commerce-extensions/create-a-custom-field#request) or [updating](/docs/api/commerce-extensions/update-a-custom-field#request) a Custom Field, `presentation` can be used to influence the layout and order of fields within Commerce Manager. It does not affect the order of keys within JSON, nor influence any behaviour outside of Commerce Manager. ## Reserved Slugs The following values cannot be used as a `slug` in a Custom Field. - slug - type - id - meta - created_at - updated_at - links - relationships - attributes - attribute - dimension - dimensions - weight - weights ```mdx-code-block import DocCardList from '@theme/DocCardList'; import {useCurrentSidebarCategory} from '@docusaurus/theme-common'; ``` --- ## Delete a Custom API import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Delete a Custom API Request --- ## Delete a Custom API Entry import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Delete a Custom API Entry Request --- ## Delete a Custom Field import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Delete a Custom Field Request --- ## Get a Custom API import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Get a Custom API Request `.\n","pattern":"^[a-z0-9_-]{1,63}$"},"api_type":{"type":"string","description":"Specifies a unique API type for this Custom API. Entries for this API will use this value for their `type` field. This field must be suffixed with `_ext` to distinguish it from built in APIs.\n","pattern":"^[a-z0-9_]{1,59}_ext$"},"allow_upserts":{"type":"boolean","description":"Controls whether upsert operations are allowed for Custom API Entries via the `PUT` method. When set to `true`, it allows the creation of new Custom API Entries using `PUT` if the record doesn't exist, and updates the existing record if it does. When `false`, `PUT` requests can only update existing entries.\n","default":false},"presentation":{"type":"object","description":"Optional presentation options for the Custom API.","properties":{"page":{"type":["string","null"],"description":"The page where this Custom API should be presented. The available values depend on the deployment and may change."},"section":{"type":["string","null"],"description":"The section within the page. Can only be set when `page` is also set."}}},"links":{"type":"object","properties":{"self":{"description":"Specifies the URI of the Custom API.","example":"/v2/settings/extensions/custom-apis/3fa85f64-5717-4562-b3fc-2c963f66afa6","type":["string","null"],"format":"uri","title":"LinkURI"}}},"meta":{"type":"object","properties":{"timestamps":{"type":"object","properties":{"created_at":{"type":"string","description":"Specifies the date the entity is created.","example":"2017-01-10T11:41:19.244Z"},"updated_at":{"type":"string","description":"Specifies the date the entity is last updated.","example":"2017-01-10T11:41:19.244Z"}},"title":"Timestamps"}},"title":"Meta"},"relationships":{"type":"object","properties":{"parent_apis":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier for the related Custom API. When the `type` of an object is set to `api_location` then `id` must be `/v2/extensions`.\nWhen the `type` of an object is set to `custom_api`, then `id` must be that of a Custom API that results in a relationship that does not have a depth exceeding 2 and does not result in a cycle.\n","example":"652e39d8-d613-493e-8c20-fef99ad6327a"},"type":{"type":"string","description":"Specifies the type of parent relationship, can be `custom_api` or `api_location`.","enum":["custom_api","api_location"]}}}}}}},"title":"CustomAPIRelationships"}},"title":"CustomAPI"}}}}}},"400":{"description":"Bad request. The request failed validation.","content":{"application/json":{"schema":{"required":["errors"],"properties":{"errors":{"type":"array","items":{"type":"object","required":["status","title"],"properties":{"status":{"type":"string","description":"The HTTP response code of the error.","format":"string","examples":["400"]},"title":{"type":"string","description":"A brief summary of the error.","examples":["Bad Request"]},"detail":{"type":"string","description":"Optional additional detail about the error.","examples":["The field 'name' is required"]}}}}},"title":"Errors"},"examples":{"Missing Name":{"summary":"Required field missing","value":"{\n \"errors\": [\n {\n \"title\": \"Bad Request\",\n \"status\": \"400\",\n \"detail\": \"The field 'name' is required.\"\n }\n ]\n}\n"}}}}},"404":{"description":"Not found. The requested entity does not exist.","content":{"application/json":{"schema":{"required":["errors"],"properties":{"errors":{"type":"array","items":{"type":"object","required":["status","title"],"properties":{"status":{"type":"string","description":"The HTTP response code of the error.","format":"string","examples":["400"]},"title":{"type":"string","description":"A brief summary of the error.","examples":["Bad Request"]},"detail":{"type":"string","description":"Optional additional detail about the error.","examples":["The field 'name' is required"]}}}}},"title":"Errors"},"examples":{"Not Found":{"summary":"Requested entity not found","value":"{\n \"errors\": [\n {\n \"title\": \"Not Found\",\n \"status\": \"404\",\n \"detail\": \"Not found\"\n }\n ]\n}\n"}}}}},"500":{"description":"Internal server error. There was a system failure in the platform.","content":{"application/json":{"schema":{"required":["errors"],"properties":{"errors":{"type":"array","items":{"type":"object","required":["status","title"],"properties":{"status":{"type":"string","description":"The HTTP response code of the error.","format":"string","examples":["400"]},"title":{"type":"string","description":"A brief summary of the error.","examples":["Bad Request"]},"detail":{"type":"string","description":"Optional additional detail about the error.","examples":["The field 'name' is required"]}}}}},"title":"Errors"},"examples":{"Internal Server Error":{"summary":"Internal server error","value":"{\n \"errors\": [\n {\n \"title\": \"Internal Server Error\",\n \"status\": \"500\",\n \"detail\": \"there was a problem processing your request\"\n }\n ]\n}\n"}}}}}}} > --- ## Get a Custom API Entry import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Get a Custom API Entry Request --- ## Get a Custom Field import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Get a Custom Field Request --- ## Get OpenAPI Specification import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Generates an OpenAPI specification based on the Custom APIs and Custom Fields configured for the current store. This dynamically generated specification provides typed schemas for the `/v2/extensions/` endpoints. --- ## List Custom APIs import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Retrieves a list of Custom APIs ## Filtering The following operators and attributes are available for [filtering](/guides/Getting-Started/filtering) Custom APIs: | Attribute | Operators | Example | |---------------------|-------------------------------|-----------------------------------------------| | `id` | `lt`,`le`,`eq`,`gt`,`ge`,`in` | `eq(id,7e067539-6f6c-46e1-8c55-940031b36c6a)` | | `created_at` | `lt`,`le`,`eq`,`gt`,`ge` | `ge(created_at,2024-04-29T00:00:00.000Z)` | | `updated_at` | `lt`,`le`,`eq`,`gt`,`ge` | `le(updated_at,2024-04-29T00:00:00.000Z)` | | `api_type` | `eq`,`like`,`in` | `like(api_type,wishlist*)` | | `description` | `eq`,`like` | `like(description,*list*)` | | `name` | `eq`,`like` | `eq(name,"Wishlist")` | | `slug` | `eq`,`like`,`in` | `like(slug,*lists)` | | `presentation.page` | `ilike` | `ilike(presentation.page,Home)` | ## Sorting The following attributes are available for sorting. When specified, the results are sorted in ascending order based on the value of the field. To sort in descending order, prefix the attribute with `-`, for example, `-updated_at`. The default sort order is `created_at` in descending order. - `id` - `created_at` - `updated_at` - `api_type` - `name` - `slug` Request `.\n","pattern":"^[a-z0-9_-]{1,63}$"},"api_type":{"type":"string","description":"Specifies a unique API type for this Custom API. Entries for this API will use this value for their `type` field. This field must be suffixed with `_ext` to distinguish it from built in APIs.\n","pattern":"^[a-z0-9_]{1,59}_ext$"},"allow_upserts":{"type":"boolean","description":"Controls whether upsert operations are allowed for Custom API Entries via the `PUT` method. When set to `true`, it allows the creation of new Custom API Entries using `PUT` if the record doesn't exist, and updates the existing record if it does. When `false`, `PUT` requests can only update existing entries.\n","default":false},"presentation":{"type":"object","description":"Optional presentation options for the Custom API.","properties":{"page":{"type":["string","null"],"description":"The page where this Custom API should be presented. The available values depend on the deployment and may change."},"section":{"type":["string","null"],"description":"The section within the page. Can only be set when `page` is also set."}}},"links":{"type":"object","properties":{"self":{"description":"Specifies the URI of the Custom API.","example":"/v2/settings/extensions/custom-apis/3fa85f64-5717-4562-b3fc-2c963f66afa6","type":["string","null"],"format":"uri","title":"LinkURI"}}},"meta":{"type":"object","properties":{"timestamps":{"type":"object","properties":{"created_at":{"type":"string","description":"Specifies the date the entity is created.","example":"2017-01-10T11:41:19.244Z"},"updated_at":{"type":"string","description":"Specifies the date the entity is last updated.","example":"2017-01-10T11:41:19.244Z"}},"title":"Timestamps"}},"title":"Meta"},"relationships":{"type":"object","properties":{"parent_apis":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier for the related Custom API. When the `type` of an object is set to `api_location` then `id` must be `/v2/extensions`.\nWhen the `type` of an object is set to `custom_api`, then `id` must be that of a Custom API that results in a relationship that does not have a depth exceeding 2 and does not result in a cycle.\n","example":"652e39d8-d613-493e-8c20-fef99ad6327a"},"type":{"type":"string","description":"Specifies the type of parent relationship, can be `custom_api` or `api_location`.","enum":["custom_api","api_location"]}}}}}}},"title":"CustomAPIRelationships"}},"title":"CustomAPI"}},"meta":{"type":"object","properties":{"results":{"type":"object","properties":{"total":{"type":"integer","description":"Total number of results for the entire collection."},"total_method":{"type":"string","description":"The method used to calculate the total number results.","enum":["exact","lower_bound","observed"],"x-enumDescriptions":{"exact":"Indicates that the total is an exact count of results","lower_bound":"When there are more than 10,000 results, we stop counting at 10,000 and report that the count is a lower_bound.","observed":"Will indicate if there is at least one more result past the current page, this is the highest performing option as it doesn't require an extra call."}}}},"page":{"type":"object","properties":{"limit":{"type":"integer","description":"The maximum number of records for all pages.","example":100},"offset":{"type":"integer","description":"The current offset by number of pages.","example":0},"current":{"type":"integer","description":"The current number of pages.","example":1},"total":{"type":"integer","description":"The total number of pages.","example":1}}}},"title":"PaginationMeta"},"links":{"type":"object","properties":{"current":{"description":"Always the current page.","example":"/v2/settings/custom-apis?page[offset]=0&page[limit]=100","type":["string","null"],"format":"uri","title":"LinkURI"},"first":{"description":"Always the first page.","example":"/v2/settings/custom-apis?page[offset]=0&page[limit]=100","type":["string","null"],"format":"uri","title":"LinkURI"},"last":{"description":"Always `null` if there is only one page.","example":"/v2/settings/custom-apis?page[offset]=0&page[limit]=100","type":["string","null"],"format":"uri","title":"LinkURI"},"next":{"description":"Always `null` if there is only one page.","example":null,"type":["string","null"],"format":"uri","title":"LinkURI"},"prev":{"description":"Always `null` if on the first page.","example":null,"type":["string","null"],"format":"uri","title":"LinkURI"}},"title":"PaginationLinks"}}}}}},"400":{"description":"Bad request. The request failed validation.","content":{"application/json":{"schema":{"required":["errors"],"properties":{"errors":{"type":"array","items":{"type":"object","required":["status","title"],"properties":{"status":{"type":"string","description":"The HTTP response code of the error.","format":"string","examples":["400"]},"title":{"type":"string","description":"A brief summary of the error.","examples":["Bad Request"]},"detail":{"type":"string","description":"Optional additional detail about the error.","examples":["The field 'name' is required"]}}}}},"title":"Errors"},"examples":{"Bad Filter":{"summary":"Invalid field specified for filter","value":"{\n \"errors\": [\n {\n \"detail\": \"Invalid filter: unknown field [version] specified in search filter, allowed fields are [api_type created_at description id name slug updated_at]\",\n \"status\": \"400\",\n \"title\": \"Bad Request\"\n }\n ]\n}\n"}}}}},"500":{"description":"Internal server error. There was a system failure in the platform.","content":{"application/json":{"schema":{"required":["errors"],"properties":{"errors":{"type":"array","items":{"type":"object","required":["status","title"],"properties":{"status":{"type":"string","description":"The HTTP response code of the error.","format":"string","examples":["400"]},"title":{"type":"string","description":"A brief summary of the error.","examples":["Bad Request"]},"detail":{"type":"string","description":"Optional additional detail about the error.","examples":["The field 'name' is required"]}}}}},"title":"Errors"},"examples":{"Internal Server Error":{"summary":"Internal server error","value":"{\n \"errors\": [\n {\n \"title\": \"Internal Server Error\",\n \"status\": \"500\",\n \"detail\": \"there was a problem processing your request\"\n }\n ]\n}\n"}}}}}}} > --- ## List Custom API Entries import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Retrieves a list of Custom API Entries ## Filtering The following operators and attributes are available for [filtering](/guides/Getting-Started/filtering) all Custom API Entries: | Attribute | Operators | Example | |---------------|-------------------------------|-----------------------------------------------| | `id` | `lt`,`le`,`eq`,`gt`,`ge`,`in` | `eq(id,859aeba1-03c2-4822-bd4c-89afce93d7eb)` | | `created_at` | `lt`,`le`,`eq`,`gt`,`ge` | `ge(created_at,2024-04-29T00:00:00.000Z)` | | `updated_at` | `lt`,`le`,`eq`,`gt`,`ge` | `le(updated_at,2024-04-29T00:00:00.000Z)` | The following operators and attributes may be available for filtering Custom API Entries depending on how the [Custom Fields](/docs/api/commerce-extensions/create-a-custom-field) for that Custom API are configured. | Field type | Operators | |------------|-----------------------------------------------------------| | `string` | `lt`,`le`,`eq`,`gt`,`ge`,`in`,`is_null`,`like` | | `integer` | `lt`,`le`,`eq`,`gt`,`ge`,`in`,`is_null` | | `float` | `lt`,`le`,`gt`,`ge`,`in`,`is_null` | | `boolean` | `eq`,`is_null` | | `list` | `contains`,`contains_any`,`is_null`,`contains_all`(typed) | Given there is a Custom Field with `"slug": "name"` and `"field_type": "string"`. When you get all Custom API Entries with query parameter: `?filter=like(name,*wish*)`. Then you will get all Custom API Entries where `name` contains the string `wish`. :::warn For performance reasons, the `is_null` search operator will **NOT** match entries for a custom_field where the custom_entry was last updated before the custom_field existed. Updating the entry will cause the field to exist and match properly. ::: ## Sorting The following attributes are available for sorting. When specified, the results are sorted in ascending order based on the value of the field. To sort in descending order, prefix the attribute with `-`, for example, `-updated_at`. The default sort order is `created_at` in descending order. - `id` - `created_at` - `updated_at` ## Query Optimization When working with large data sets, the following practices help reduce query latency and avoid timeouts. ### Choose the right `page[total_method]` By default, every list request calculates a `lower_bound` total, which counts up to 10,000 matching records. If you only need to know whether a next page exists (for example, in an infinite-scroll UI), set `page[total_method]=observed`. This skips the full count and only checks for one record beyond the current page, which can significantly reduce response times on large data sets. | Method | Behavior | Best for | |----------------|---------------------------------------------------------------------------|--------------------------------------------| | `lower_bound` | Counts up to 10,000 records; reports exact total or indicates lower bound | Displaying a total count to users | | `observed` | Checks only if a next page exists beyond the current offset and limit | Infinite scroll, cursor-style pagination | ### Skip sorting when order doesn't matter Setting `sort=null` disables sorting entirely. If your use case does not require a specific order (for example, background sync jobs), this avoids the overhead of ordering results and can improve throughput. ### Narrow your filters Queries that filter on Custom Fields are more efficient when the filter is selective. Prefer exact-match operators (`eq`, `in`) over range or wildcard operators (`like`, `lt`/`le`/`gt`/`ge`) where possible, and combine multiple filters to reduce the result set early. Request --- ## List Custom Fields import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Retrieves a list of Custom Fields ## Filtering The following operators and attributes are available for [filtering](/guides/Getting-Started/filtering) Custom Fields: | Attribute | Operators | Example | |---------------|-------------------------------|-----------------------------------------------| | `id` | `lt`,`le`,`eq`,`gt`,`ge`,`in` | `eq(id,859aeba1-03c2-4822-bd4c-89afce93d7eb)` | | `created_at` | `lt`,`le`,`eq`,`gt`,`ge` | `ge(created_at,2024-04-29T00:00:00.000Z)` | | `updated_at` | `lt`,`le`,`eq`,`gt`,`ge` | `le(updated_at,2024-04-29T00:00:00.000Z)` | | `description` | `eq`,`like` | `like(description,*confidential*)` | | `field_type` | `eq`,`in` | `eq(field_type,string)` | | `name` | `eq`,`like` | `eq(name,"Last Name")` | | `slug` | `eq`,`like`,`in` | `like(slug,*private*)` | ## Sorting The following attributes are available for sorting. When specified, the results are sorted in ascending order based on the value of the field. To sort in descending order, prefix the attribute with `-`, for example, `-updated_at`. The default sort order is `created_at` in descending order. - `id` - `created_at` - `updated_at` - `field_type` - `name` - `slug` Request --- ## Update a Custom API import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Update a Custom API Request `.\n","pattern":"^[a-z0-9_-]{1,63}$"},"allow_upserts":{"type":"boolean","description":"Controls whether upsert operations are allowed for Custom API Entries via the `PUT` method. When set to `true`, it allows the creation of new Custom API Entries using `PUT` if the record doesn't exist, and updates the existing record if it does. When `false`, `PUT` requests can only update existing entries.\n","default":false},"presentation":{"type":"object","description":"Optional presentation options for the Custom API.","properties":{"page":{"type":["string","null"],"description":"The page where this Custom API should be presented. The available values depend on the deployment and may change."},"section":{"type":["string","null"],"description":"The section within the page. Can only be set when `page` is also set.","maxLength":64}}},"relationships":{"type":"object","properties":{"parent_apis":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier for the related Custom API. When the `type` of an object is set to `api_location` then `id` must be `/v2/extensions`.\nWhen the `type` of an object is set to `custom_api`, then `id` must be that of a Custom API that results in a relationship that does not have a depth exceeding 2 and does not result in a cycle.\n","example":"652e39d8-d613-493e-8c20-fef99ad6327a"},"type":{"type":"string","description":"Specifies the type of parent relationship, can be `custom_api` or `api_location`.","enum":["custom_api","api_location"]}}}}}}},"title":"CustomAPIRelationships"}}}}},"examples":{"Update Example":{"summary":"Update a Custom API","value":{"data":{"type":"custom_api","name":"Wishlists","description":"Specifies the description for this Custom API.","slug":"wishlists","relationships":{"parent_apis":{"data":[{"id":"652e39d8-d613-493e-8c20-fef99ad6327a","type":"custom_api"}]}}}}}}}}}} > `.\n","pattern":"^[a-z0-9_-]{1,63}$"},"api_type":{"type":"string","description":"Specifies a unique API type for this Custom API. Entries for this API will use this value for their `type` field. This field must be suffixed with `_ext` to distinguish it from built in APIs.\n","pattern":"^[a-z0-9_]{1,59}_ext$"},"allow_upserts":{"type":"boolean","description":"Controls whether upsert operations are allowed for Custom API Entries via the `PUT` method. When set to `true`, it allows the creation of new Custom API Entries using `PUT` if the record doesn't exist, and updates the existing record if it does. When `false`, `PUT` requests can only update existing entries.\n","default":false},"presentation":{"type":"object","description":"Optional presentation options for the Custom API.","properties":{"page":{"type":["string","null"],"description":"The page where this Custom API should be presented. The available values depend on the deployment and may change."},"section":{"type":["string","null"],"description":"The section within the page. Can only be set when `page` is also set."}}},"links":{"type":"object","properties":{"self":{"description":"Specifies the URI of the Custom API.","example":"/v2/settings/extensions/custom-apis/3fa85f64-5717-4562-b3fc-2c963f66afa6","type":["string","null"],"format":"uri","title":"LinkURI"}}},"meta":{"type":"object","properties":{"timestamps":{"type":"object","properties":{"created_at":{"type":"string","description":"Specifies the date the entity is created.","example":"2017-01-10T11:41:19.244Z"},"updated_at":{"type":"string","description":"Specifies the date the entity is last updated.","example":"2017-01-10T11:41:19.244Z"}},"title":"Timestamps"}},"title":"Meta"},"relationships":{"type":"object","properties":{"parent_apis":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier for the related Custom API. When the `type` of an object is set to `api_location` then `id` must be `/v2/extensions`.\nWhen the `type` of an object is set to `custom_api`, then `id` must be that of a Custom API that results in a relationship that does not have a depth exceeding 2 and does not result in a cycle.\n","example":"652e39d8-d613-493e-8c20-fef99ad6327a"},"type":{"type":"string","description":"Specifies the type of parent relationship, can be `custom_api` or `api_location`.","enum":["custom_api","api_location"]}}}}}}},"title":"CustomAPIRelationships"}},"title":"CustomAPI"}}}}}},"400":{"description":"Bad request. The request failed validation.","content":{"application/json":{"schema":{"required":["errors"],"properties":{"errors":{"type":"array","items":{"type":"object","required":["status","title"],"properties":{"status":{"type":"string","description":"The HTTP response code of the error.","format":"string","examples":["400"]},"title":{"type":"string","description":"A brief summary of the error.","examples":["Bad Request"]},"detail":{"type":"string","description":"Optional additional detail about the error.","examples":["The field 'name' is required"]}}}}},"title":"Errors"},"examples":{"Missing Name":{"summary":"Required field missing","value":"{\n \"errors\": [\n {\n \"title\": \"Bad Request\",\n \"status\": \"400\",\n \"detail\": \"The field 'name' is required.\"\n }\n ]\n}\n"}}}}},"404":{"description":"Not found. The requested entity does not exist.","content":{"application/json":{"schema":{"required":["errors"],"properties":{"errors":{"type":"array","items":{"type":"object","required":["status","title"],"properties":{"status":{"type":"string","description":"The HTTP response code of the error.","format":"string","examples":["400"]},"title":{"type":"string","description":"A brief summary of the error.","examples":["Bad Request"]},"detail":{"type":"string","description":"Optional additional detail about the error.","examples":["The field 'name' is required"]}}}}},"title":"Errors"},"examples":{"Not Found":{"summary":"Requested entity not found","value":"{\n \"errors\": [\n {\n \"title\": \"Not Found\",\n \"status\": \"404\",\n \"detail\": \"Not found\"\n }\n ]\n}\n"}}}}},"409":{"description":"Unable to perform the operation at this time.","content":{"application/json":{"schema":{"required":["errors"],"properties":{"errors":{"type":"array","items":{"type":"object","required":["status","title"],"properties":{"status":{"type":"string","description":"The HTTP response code of the error.","format":"string","examples":["400"]},"title":{"type":"string","description":"A brief summary of the error.","examples":["Bad Request"]},"detail":{"type":"string","description":"Optional additional detail about the error.","examples":["The field 'name' is required"]}}}}},"title":"Errors"},"examples":{"Duplicate Custom API":{"summary":"Duplicate Custom API","value":"{\n \"errors\": [\n {\n \"title\": \"Conflict\",\n \"status\": \"409\",\n \"detail\": \"custom_api with the given api_type already exists\"\n }\n ]\n}\n"},"Duplicate Custom Field":{"summary":"Duplicate Custom Field","value":"{\n \"errors\": [\n {\n \"title\": \"Conflict\",\n \"status\": \"409\",\n \"detail\": \"custom_field with the given slug already exists\"\n }\n ]\n}\n"}}}}},"500":{"description":"Internal server error. There was a system failure in the platform.","content":{"application/json":{"schema":{"required":["errors"],"properties":{"errors":{"type":"array","items":{"type":"object","required":["status","title"],"properties":{"status":{"type":"string","description":"The HTTP response code of the error.","format":"string","examples":["400"]},"title":{"type":"string","description":"A brief summary of the error.","examples":["Bad Request"]},"detail":{"type":"string","description":"Optional additional detail about the error.","examples":["The field 'name' is required"]}}}}},"title":"Errors"},"examples":{"Internal Server Error":{"summary":"Internal server error","value":"{\n \"errors\": [\n {\n \"title\": \"Internal Server Error\",\n \"status\": \"500\",\n \"detail\": \"there was a problem processing your request\"\n }\n ]\n}\n"}}}}}}} > --- ## Update a Custom API Entry import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Update a Custom API Entry Request --- ## Update a Custom Field import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Update a Custom Field Request --- ## Addresses Introduction(Customer-addresses) import ApiLogo from "@theme/ApiLogo"; import Heading from "@theme/Heading"; import SchemaTabs from "@theme/SchemaTabs"; import TabItem from "@theme/TabItem"; import Export from "@theme/ApiExplorer/Export"; The Addresses API allows you to organize customer addresses. Addresses are a sub-resource of a `customer`, a customer can have multiple addresses, such as home, work, and neighbour. You can use a customer address with an [implicit access token](/docs/api/authentication/create-an-access-token), which is recommended for client-side interactions. You can also use a [client_credentials access token](/docs/api/authentication/create-an-access-token), which is recommended for back-end interactions. Security Scheme Type: http HTTP Authorization Scheme: bearer Contact Elastic Path: [support@elasticpath.com](mailto:support@elasticpath.com) URL: [https://www.elasticpath.com](https://www.elasticpath.com) License MIT --- ## Customer Addresses The API to organize customer addresses. ```mdx-code-block import DocCardList from '@theme/DocCardList'; import {useCurrentSidebarCategory} from '@docusaurus/theme-common'; ``` --- ## Delete a Customer Address import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Delete an address for a Customer. Request --- ## Get an Customer Address import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Get an address for a Customer. Request --- ## Get Customer Addresses import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Get all addresses for a Customer. You can use pagination with this resource. For more information, see [pagination](/guides/Getting-Started/pagination). ### Filtering The following operators and attributes are available for [filtering](/guides/Getting-Started/filtering) addresses: | Attribute | Operators | Example | |----------------|---------------------------------|---------------------------------------| | `name` | `eq`,`in`,`like`,`ilike`,`text` | `ilike(name,"*home*")` | | `first_name` | `eq`,`in`,`like`,`ilike`,`text` | `ilike(first_name,"Ron*")` | | `last_name` | `eq`,`in`,`like`,`ilike`,`text` | `ilike(last_name,"*swan*")` | | `phone_number` | `eq`,`in`,`like`,`ilike`,`text` | `ilike(phone_number,"*555*")` | | `company_name` | `eq`,`in`,`like`,`ilike`,`text` | `ilike(company_name,"*enterprises*")` | | `instructions` | `eq`,`in`,`like`,`ilike`,`text` | `text(instructions,"behind bin")` | | `line_1` | `eq`,`in`,`like`,`ilike`,`text` | `ilike(line_1,"*Sunny Street*")` | | `line_2` | `eq`,`in`,`like`,`ilike`,`text` | `ilike(line_2,"*Unit*")` | | `city` | `eq`,`in`,`like`,`ilike`,`text` | `eq(city,"Sunny Town")` | | `county` | `eq`,`in`,`like`,`ilike`,`text` | `eq(county,"Sunnyville")` | | `region` | `eq`,`in`,`like`,`ilike`,`text` | `eq(region,"California")` | | `postcode` | `eq`,`in`,`like`,`ilike`,`text` | `eq(postcode,"SU33 1YY")` | | `country` | `eq`,`in`,`like`,`ilike`,`text` | `eq(country,"GB")` | Request --- ## Create a Customer Address import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Create an address for a Customer. Request --- ## Update an Customer Address import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Update an address for a Customer. Request --- ## Create Job import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Create a Job to export orders to a CSV file. Jobs automatically expire one week after creation. You must fetch the exported data before the jobs expire. Request --- ## Exporter Service API import ApiLogo from "@theme/ApiLogo"; import Heading from "@theme/Heading"; import SchemaTabs from "@theme/SchemaTabs"; import TabItem from "@theme/TabItem"; import Export from "@theme/ApiExplorer/Export"; Use the Exporter Service API to export orders to a Comma-Separated Values (CSV) file. When you run the `export order` endpoint, a job is created. Security Scheme Type: http HTTP Authorization Scheme: bearer --- ## Get a Job File import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Retrieves a link to the CSV file that contains your exported order. Request --- ## Get a Job import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Retrieves the specified job. Request --- ## Get All Jobs import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; You can use this endpoint to display the status of your jobs. --- ## Jobs Jobs have the following characteristics: - Jobs are asynchronous. - This process is repeated until all jobs are processed. - Jobs have a different status, depending on where a job is in its lifecycle. - Jobs are processed one at a time. You can continue to send requests using endpoints that function as jobs, but those jobs are queued. In other words, Commerce looks for any jobs that have a status of PENDING and starts the job with the earliest created date. - Jobs include the data used when an endpoint is run. - Jobs report messages and/or errors to help you understand the reasons for any failed jobs. ### Job Lifecycle A job can have the following status: - PENDING - Commerce has received the request but is currently busy processing other requests. - STARTED - Commerce has started processing the job. - SUCCESS - The job has successfully completed. - FAILED - The job has failed. ```mdx-code-block import DocCardList from '@theme/DocCardList'; import {useCurrentSidebarCategory} from '@docusaurus/theme-common'; ``` --- ## Create a Field import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; - For Commerce, this endpoint creates a field. - For Product Experience Manager, this endpoint creates an attribute. Request --- ## Create a Flow import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; - For Commerce, this endpoint creates a flow. - For Product Experience Manager, this endpoint creates a template. :::caution Custom names and values prefixed with $ are not supported. ::: Request --- ## Create an Entry Relationship import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; - In Commerce, create an entry relationship to one or more resources. If any relationships already exist, the ones made in the request are added to them. - In Product Experience Manager, create an entry relationship with the product to which you want to associate the template. Request --- ## Create an Entry import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; - For Commerce, this endpoint creates an entry for a flow. - For Product Experience Manager, this endpoint creates an entry for a template. Request --- ## Delete a Field import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; - For Commerce, this endpoint deletes a field. - For Product Experience Manager, this endpoint deletes an attribute. Request --- ## Delete a Flow import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; - For Commerce, this endpoint deletes a flow. We recommend that you remove all the fields assigned to a flow before deleting a flow. - For Product Experience Manager, this endpoint deletes a template. We recommend that you remove all the attributes assigned to a template before deleting a template. Request --- ## Delete an Entry Relationship import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; - In Commerce, deletes an entry relationship to one or more resources. - In Product Experience Manager, deletes an entry relationship with the product to which you want to associate the template. Request --- ## Delete an Entry import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; - For Commerce, this endpoint deletes an entry from a flow. - For Product Experience Manager, this endpoint deletes an entry from a template. Request --- ## Entries ### Entries in Commerce Entries hold the pieces of data collected within the fields. If your flow has more than one field related to it, you see multiple field slugs. ### Entries in Product Experience Manager Entries hold the pieces of data collected within the attributes. If your template has more than one attribute related to it, you see multiple attribute slugs. ```mdx-code-block import DocCardList from '@theme/DocCardList'; import {useCurrentSidebarCategory} from '@docusaurus/theme-common'; ``` --- ## Entry Relationships ### Entry Relationships in Commerce When you create a field that uses `relationship` as a `field_type`, you update your entry values using the `Entry Relationship` endpoints. ### Entry Relationships in Product Experience Manager Once you have created your templates, you must associate them with your products using the `Entry Relationship` endpoints. ```mdx-code-block import DocCardList from '@theme/DocCardList'; import {useCurrentSidebarCategory} from '@docusaurus/theme-common'; ``` --- ## Fields With fields, you can: - in Commerce, use a field in your flows to represent single field of data (for example a `Product Rating`) to be applied to an entity - in Product Experience Manager, use an attribute in your template to attach a characteristic like `color` to a product. A field/attribute represents a single piece of data. All fields/attributes have a `field_type` (`string`, `integer`, `boolean`, `date` or `relationship`), a default value, and an optional set of validation rules. :::caution - Custom names and values prefixed with `$` are not supported. - There is a hard limit of 100 fields per flow. - You can configure default values for fields. If you choose to do so, you must ensure that your default field values comply with your validation rules. ::: #### Field/Attribute Validation Rules When creating a field/attribute, you can add validation to the values that are stored. The validation you use depends on the `field_type` of the field/attribute. Each validation rule is expressed as a validation rule object. #### `string` / `enum` Must be one of a predefined collection of strings. If you leave the field blank or enter an incorrect value then an `Invalid Value` error is displayed. | Attribute | Type | Description | | :--- | :--- | :--- | | `type` | `string` | `enum` | | `options` | `array[string]` | An array of valid string values. | ##### `string` / `email` Must be a valid email address. | Attribute | Type | Description | | :--- | :--- | :--- | | `type` | `string` | `email` | ##### `string` / `slug` Can contain only letters, numbers, hyphens and underscores. | Attribute | Type | Description | | :--- | :--- | :--- | | `type` | `string` | `slug` | ##### `integer` / `between` Must be between the two provided values. | Attribute | Type | Description | | :--- | :--- | :--- | | `type` | `string` | `enum` | | `options` | `object` | An object containing `from` and `to` integers. | ##### `integer` / `enum` Must be one of a predefined collection of integers. | Attribute | Type | Description | | :--- | :--- | :--- | | `type` | `string` | `enum` | | `options` | `array[integer]` | An array of valid integer values. | ##### `float` / `between` Must be between the two provided values. | Attribute | Type | Description | | :--- | :--- | :--- | | `type` | `string` | `enum` | | `options` | `object` | An object containing `from` and `to` floats. | ##### `float` / `enum` Must be one of a predefined collection of floats. | Attribute | Type | Description | | :--- | :--- | :--- | | `type` | `string` | `enum` | | `options` | `array[float]` | An array of valid float values. | #### `date` / `enum` Must be one of a predefined collection of dates. | Attribute | Type | Description | | :--- | :--- | :--- | | `type` | `string` | `enum` | | `options` | `array[string]` | An array of valid date values as strings \(`YYYY-MM-DD HH:MM:SS` - time is optional\). | ##### `relationship` / `one-to-many` :::caution This only applies to Commerce. You cannot use relationships in Product Experience Manager templates. ::: Allows multiple relationships to be created. | Attribute | Type | Description | | :--- | :--- | :--- | | `type` | `string` | `one-to-many` | | `to` | `string` | The entity type you are making relationships with in singular form (for example, `product`). | ##### `relationship` / `one-to-one` :::caution This only applies to Commerce. You cannot use relationships in Product Experience Manager templates. ::: Allows only a single relationships to be created on an entry. | Attribute | Type | Description | | :--- | :--- | :--- | | `type` | `string` | `one-to-one` | | `to` | `string` | The entity type you are making relationships with in singular form (for example, `customer`). | ```mdx-code-block import DocCardList from '@theme/DocCardList'; import {useCurrentSidebarCategory} from '@docusaurus/theme-common'; ``` --- ## Flows Service Introduction import ApiLogo from "@theme/ApiLogo"; import Heading from "@theme/Heading"; import SchemaTabs from "@theme/SchemaTabs"; import TabItem from "@theme/TabItem"; import Export from "@theme/ApiExplorer/Export"; With flows you can extend the capabilities of Commerce and Product Experience Manager at both organization and store level, and apply Composable Commerce to almost any use case. ### Flows in Commerce You can define custom data fields for the resources that you use in your store or organization, such as adding more fields to the `customer` resource. You can also create new resources, such as a `wishlist` resource to support wishlists in your store. :::note [Custom APIs](/docs/api/commerce-extensions/custom-ap-is#custom-apis-vs-non-core-flows) are the next generation of Non-Core Flows. Flows are not going anywhere, but Custom APIs offer enhanced capabilities. We recommend using Custom APIs for any of your new use cases. ::: :::caution - In an organization, not all resources are available. See [**Extend a resource**](https://elasticpath.dev/guides/Custom%20Data/extend-any-resource) for a list of organization resources that can be extended. - If you store any sensitive Personal Identifiable Information (PII) or non-public data on your site, ensure that you do not use this data in flows to avoid potential unauthorized access to the data. For more information, see [**Permissions**](/docs/authentication/tokens/permissions). ::: ### Templates in Product Experience Manager Templates allow you to attach a specific set of attributes to your products. - You can use templates to define characteristics of your product, for example, a product specification. For example, a *Book* template might contain attributes, such as *ISBN*, *Author*, *Number of pages*, *Year Published*, or *Condition (New/Used)*. - You can use templates for Search Engine Optimization (SEO). When you assign template attributes such as, *care instructions* or *fabric*, to a shirt and a shopper searches for a specific item, attributes help stores to return the products that match the search criteria. For example, when a shopper searches for a large blue shirt, all shirts that are large and blue are returned in the search result. Security Scheme Type: http HTTP Authorization Scheme: bearer --- ## Flows ### Flows in Commerce There are two scenarios for using flows: - Extend an existing resource, such as customers and orders. - Create a new resource, such as a blog, wishlist, or customer review. #### Extend an existing resource The most common usage of the Flows API is to extend existing resources, such as `customers` and `orders`. These types of resources are called core flows and are handled differently than non-core flows. See [**Core and non-core flows**](#core-and-non-core-flows). For example, you can extend the `customer` resource to store custom data, such as a `user_profile` field for customers. Or you might want to add an `age` field to store a customer's age. Extending a resource applies only to core flows. When creating a new flow, make sure the `slug` matches that of a core resource listed in the following table. | Flow slug | Description | Availability Level | |:--------------------------------------------|:-------------------------------| :---| | `accounts` | Extend the [`account`](/docs/api/accounts/account-management-introduction) object. | Store | | `account-members` | Extend the [`account-members`](/docs/api/accounts/account-members) object. | Store | | `account-memberships` | Extend the [`account-membership`](/docs/api/accounts/account-membership) object. | Store | | `addresses` | Extend the [`address`](/docs/api/addresses/account-addresses) object. | Store | | `authentication-realms` | Extend the [`authentication-realms`](/docs/api/single-sign-on/authentication-realms) object. | Store | | `carts` | Extend the [`carts`](/docs/api/carts/carts-checkout-orders-introduction) object. | Organization/Store | | `cart_items` | Extend the [`cart_item`](/docs/api/carts/cart-items) object. | Organization/Store | | `customers` | Extend the [`customer`](/docs/customer-management/customer-management-api/customer-management-api-overview) object. **Note**: Please use Account Management for all new frontend experiences. | n/a | | `oidc-profiles` | Extend the [`oidc-profiles`](/docs/api/single-sign-on/oidc-profiles) object. | Store | | `order_items` | Extend the [`order_item`](/docs/api/carts/get-order-items) object. | Organization/Store | | `orders` | Extend the [`order`](/docs/api/carts/orders) object. | Organization/Store | | `password-profiles` | Extend the [`password-profiles`](/docs/api/single-sign-on/password-profiles) object. | Store | | `products` | Extend the [`product`](/docs/api/pxm/products/products) object. | Store | | `promotions` | Extend the [`promotion`](/docs/api/promotions/promotions-standard-introduction) object. | Store | | `rule-promotions` | Extend the [`rule-promotion`](/docs/api/promotions-builder/create-rule-promotion) object. | Store | | `user-authentication-info` | Extend the [`user-authentication-info`](/docs/api/single-sign-on/user-authentication-infos) object. | Store | | `user-authentication-oidc-profile-info` | Extend the [`user-authentication-oidc-profile-info`](/docs/api/single-sign-on/user-authentication-oidc-profile-infos) object. | Store | | `user-authentication-password-profile-info` | Extend the [`user-authentication-password-profile-info`](/docs/api/single-sign-on/user-authentication-password-profile-infos) object. | Store | | `catalogs` | Extend the [`catalog`](/docs/api/pxm/catalog/catalogs) object. It will not extend the [`catalog-release`](/docs/api/pxm/catalog/releases) object. | Store | | `shipping-groups` | Extend the [`shipping-group`](/docs/api/carts/create-shipping-group) object. | Store | #### Create a new resource You can create new resources to support product reviews, wish lists, blog articles, staff profile pages, and many more. These non-core flows are referred to as custom flows. See [**Core and non-core flows**](#core-and-non-core-flows). :::note [Custom APIs](/docs/api/commerce-extensions/custom-ap-is#custom-apis-vs-non-core-flows) are the next generation of Non-Core Flows. Flows are not going anywhere, but Custom APIs offer enhanced capabilities. We recommend using Custom APIs for any of your new use cases. ::: #### Core and non-core flows The following table describes the differences between core and non-core flows: | Core Flows | Non-core Flows | |:--------------------------------------------------------------|:-------------| | Extend an existing resource. | Create a new resource. | | Entries managed automatically by Commerce. | Create and manage entries manually. | | Requests are sent to the `fields` endpoint. | Requests are sent to the `entries` endpoint. | :::caution You cannot delete core flows after creating them with the API or Commerce Manager. ::: #### Flows taxonomy Fields and entries are an integral part of flows. A flow describes a collection of fields. A field represents a single field of data. An entry is a specific instance of a flow, and is associated with a specific instance of an entity, such as a single customer. Entries for core flows (existing resources) are managed automatically for you. In database terms, you can think of flows as tables, fields as columns, and entries as database records. ### Templates in Product Experience Manager Templates allow you to attach a specific set of attributes to your products. - You can use templates to define characteristics of your products. - You can use templates for Search Engine Optimization (SEO). #### Template Taxonomy Attributes and entries are integral to templates. A template describes a collection of attributes. An attribute represents a single characteristic, like color. An entry is a specific instance of an attribute, for example, blue, and is associated with a specific product. A template is exactly the same as a flow except it has a different naming convention. The name of a template is in the format **products(*slug*)** where *slug* is the slug of a template. #### Associating templates with products Once you have created your template, and [**associated**](/docs/api/flows/create-an-entry-relationship) the temp with a product in Product Experience Manager, it becomes a template. For example, if you create a template with a slug of `SizeGuide` then the template name is **products(SizeGuide)**. You can then [**associate**](/docs/api/flows/create-an-entry-relationship) this template to all clothing products in your store and the slug is included in all the responses that contain products. You can create product templates for both organization and store. In addition, stores can use organization templates for store-level products. For more information about adding attributes, see [**Fields**](/docs/api/flows/fields). ```mdx-code-block import DocCardList from '@theme/DocCardList'; import {useCurrentSidebarCategory} from '@docusaurus/theme-common'; ``` --- ## Get a Field import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; - For Commerce, this endpoint retrieves a field. - For Product Experience Manager, this endpoint retrieves an attribute. Request --- ## Get a Flow import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; - For Commerce, this endpoint retrieves a flow. - For Product Experience Manager, this endpoint retrieves a template. Request --- ## Get all Entries import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; - For Commerce, this endpoint retrieves all entries for a flow. - For Product Experience Manager, this endpoint retrieves all entries for a template. Request --- ## Get all Fields by Flow import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Get all Fields by Flow Request --- ## Get all Fields import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; - For Commerce, this endpoint retrieves all fields in a flow. - For Product Experience Manager, this endpoint retrieves all attributes in a template. Request --- ## Get all Flows import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; - For Commerce, this endpoint retrieves a list of flows. - For Product Experience Manager, this endpoint retrieves a list of templates. Request --- ## Get an Entry import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; - For Commerce, this endpoint retrieves an entry from a flow. - For Product Experience Manager, this endpoint retrieves an entry from a template. Request --- ## Update a Field import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; - For Commerce, this endpoint updates a field. - For Product Experience Manager, this endpoint updates an attribute. Specify whichever attributes you want to change. The values of the other attributes remain the same. If the attributes section is empty, the field/attribute is not updated. Request --- ## Update a Flow import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; - For Commerce, this endpoint updates a flow. - For Product Experience Manager, this endpoint updates a template. Specify whichever attributes you want to change. The values of the other attributes remain the same. If the attributes section is empty, the flow/template is not updated. Request --- ## Update an Entry Relationship import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; - In Commerce, updates an entry relationship to one or more resources. If any relationships already exist, the ones made in the request are added to them. - In Product Experience Manager, updates an entry relationship with the product to which you want to associate the template. Request --- ## Update an Entry import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; - For Commerce, this endpoint updates an entry for a flow. - For Product Experience Manager, this endpoint updates an entry for a template. Request --- ## Create an integration import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Create an integration. Request --- ## Delete an integration import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Deletes the Integration for the given UUID Request --- ## Get an integration import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Returns the integration for the given UUID. Request --- ## Integrations Introduction import ApiLogo from "@theme/ApiLogo"; import Heading from "@theme/Heading"; import SchemaTabs from "@theme/SchemaTabs"; import TabItem from "@theme/TabItem"; import Export from "@theme/ApiExplorer/Export"; You can integrate Commerce with your external systems like enterprise resource planning, order management, fulfilment, and other systems, ensuring that buying is quick and easy for your shoppers. Events are actions that occur in your commerce workflow, such as a customer changing their address or an order changing status from created to paid. You can create custom functions that perform additional processing outside of Commerce, and create integrations so that when an event occurs in your store, the custom function is run. For example: - When a customer updates their address, the Customer Relationship Management system is updated with the change. - When an order status changes to paid, the affected stock in an inventory management system is reduced by the number of items in the order. Events are processed concurrently. This means that events may not be delivered in the order they are created. For example, if the status of an order is updated multiple times, the events may not be delivered in the same sequence they were updated. Integration events operate on an "at least once" delivery policy. We aim to deliver messages within 15 seconds except in cases of high load. Ensure that you design your receiving code accordingly. :::note For a list of all the events that can be used, see [Observable Events](#observable-events). ::: You can integrate Commerce with your external systems using: - Webhooks - Message Queuing Services ### Webhooks You can use Webhooks to deliver Commerce events to a configured HTTP endpoint. ### Message Queuing Services You can deliver Commerce events to messages queues through the following message queuing services: - Amazon Simple Queuing Service (SQS) - Message queuing services that support the Message Simple Text Orientated Messaging Protocol (STOMP), for example, Amazon MQ. :::note You can integrate Amazon SQS and message queuing services that support STOMP through the Integrations API. You can view the integration details in Commerce Manager > **SYSTEM** > **Store Settings** > **Webhooks**. For more information, see [Create an integration](/docs/api/integrations/create-integration). ::: ### Integration Types Commerce supports the following integration types: - Using [webhooks](/docs/api/integrations/create-integration), you can have Commerce deliver events to a configured HTTP endpoint. :::caution Webhooks that return anything other than a 2XX status code, or take more than 10 seconds to respond, are considered failed. - Using [message queuing services](#message-queuing-services), you can deliver Commerce events to a message queue. The advantages of using message queuing services over webhooks are: - A temporary failure of a webhook endpoint can result in lost events. However, if messages are on your own queue, you can leave the event on the queue to retry later. - If events take a long time to process, a webhook can timeout, but delivery to a queue is always going to take the same amount of time. ::: ### Webhooks An integration with an `integration_type` of [`webhook`](/docs/api/integrations/create-integration) delivers its events to a configured HTTP endpoint. ### Message Queuing Services Elastic Path allows you to integrate with the following message queuing services: - Amazon Simple Message Queuing Service (SQS). - Message queuing services that use Simple Text Orientated Messaging Protocol (STOMP), for example, Amazon MQ. :::caution You can integrate Amazon SQS and message queuing services that support STOMP through the Integrations API. You can view the integration details in Commerce Manager > **SYSTEM** > **Store Settings** > **Webhooks**. For more information, see [Create an integration](/docs/api/integrations/create-integration). ::: #### Amazon Simple Message Queuing Service (SQS) An integration with an `integration_type` of [`aws_sqs`](/docs/api/integrations/create-integration) delivers its events directly into the configured AWS SQS queue. These messages can be processed by any appropriate means, such as a Lambda function. For more information about creating Simple Queue Service (SQS) queues, see the [Simple Queue Service (SQS)](https://elasticpath.dev/guides/How-To/Integrations/sqs-queues) and [SQS Events with CloudFormation](https://elasticpath.dev/guides/How-To/Integrations/sqs-queues-cloudformation) sections. #### Simple Text Orientated Messaging Protocol (STOMP) An integration with the [`stomp`](/docs/api/integrations/create-integration) integration type delivers its events directly into a configured queue. Any message queuing service that uses STOMP, such as Amazon MQ, can process these messages. For more information, see the documentation provided with the message queuing service you are using. ### Webhooks The payload delivered to your webhook `url` contains information about the fired event. The payload attributes and types are defined in the following table. | Attribute | Type | Description | | :------------- | :------------------------------- | :------------------------------------------------------------------------------------------------ | | `id` | `string` | A unique ID for this event. | | `integration` | `object` | The events `integration_type` being fired. | | `triggered_by` | `string` | The [observable events](#observable-events) that triggered this event. | | `attempt` | `integer` | The number of attempts to deliver this event. | | `resources` | `string` | The resources affected by this event. This field is now deprecated. Please use `payload` instead. | | `payload` | `object` | The resources affected by this event. | :::note Store-level events contain `store_id` and `org_id` whereas, organization-level events contain only `org_id`. ::: ### Example: Typical payload The following example payload [observes](#observable-events) the `order.paid` event. The configured URL receives the following payload. ```javascript { "id": "21a361c9-b117-4d16-be2d-5ed2dbdaa95b", "triggered_by": "order.paid", "attempt": 1, "integration": { "id": "af7bbcc7-f77f-4a8f-abdb-4f039c5c9d81", "integration_type": "webhook", "name": "Order paid notification", "description": "Fire an event on order paid" }, "resources": "{\"data\":{\"type\":\"order\",\"id\":\"1d67160d-dacb-43ed-80ef-c3c4e7ddf764\",\"status\":\"complete\",\"payment\":\"paid\",\"shipping\":\"unfulfilled\",\"customer\":{\"name\":\"Ron Swanson\",\"email\":\"ron.swanson@moltin.com\"},\"shipping_address\":{\"first_name\":\"Jack\",\"last_name\":\"Macdowall\",\"phone_number\":\"123456789\",\"company_name\":\"Macdowalls\",\"line_1\":\"Second Floor, British India House\",\"line_2\":\"15 Carliol Square\",\"city\":\"Newcastle upon Tyne\",\"postcode\":\"NE1 6UF\",\"county\":\"Tyne and Wear\",\"country\":\"GB\",\"instructions\":\"Leave in porch\"},\"billing_address\":{\"first_name\":\"Jack\",\"last_name\":\"Macdowall\",\"company_name\":\"Macdowalls\",\"line_1\":\"Second Floor, British India House\",\"line_2\":\"15 Carliol Square\",\"city\":\"Newcastle upon Tyne\",\"postcode\":\"NE1 6UF\",\"county\":\"Tyne and Wear\",\"country\":\"GB\"},\"links\":{},\"meta\":{\"display_price\":{\"with_tax\":{\"amount\":10000,\"currency\":\"GBP\",\"formatted\":\"£100.00\"},\"without_tax\":{\"amount\":10000,\"currency\":\"GBP\",\"formatted\":\"£100.00\"},\"tax\":{\"amount\":0,\"currency\":\"GBP\",\"formatted\":\"£0.00\"}},\"timestamps\":{\"created_at\":\"2019-07-04T11:12:23Z\",\"updated_at\":\"2019-07-04T11:12:23Z\"}},\"relationships\":{\"items\":{\"data\":[{\"type\":\"item\",\"id\":\"395763ee-1878-4aa0-a7a2-8d4877310d6b\"}]}}},\"included\":{\"items\":[{\"type\":\"order_item\",\"id\":\"395763ee-1878-4aa0-a7a2-8d4877310d6b\",\"quantity\":1,\"product_id\":\"4f28f222-aa5b-442c-9ce9-c223dc7cf15a\",\"name\":\"Spam Fritters\",\"sku\":\"spam-fritters-0716\",\"unit_price\":{\"amount\":10000,\"currency\":\"GBP\",\"includes_tax\":false},\"value\":{\"amount\":10000,\"currency\":\"GBP\",\"includes_tax\":false},\"links\":{},\"meta\":{\"display_price\":{\"with_tax\":{\"unit\":{\"amount\":10000,\"currency\":\"GBP\",\"formatted\":\"£100.00\"},\"value\":{\"amount\":10000,\"currency\":\"GBP\",\"formatted\":\"£100.00\"}},\"without_tax\":{\"unit\":{\"amount\":10000,\"currency\":\"GBP\",\"formatted\":\"£100.00\"},\"value\":{\"amount\":10000,\"currency\":\"GBP\",\"formatted\":\"£100.00\"}},\"tax\":{\"unit\":{\"amount\":0,\"currency\":\"GBP\",\"formatted\":\"£0.00\"},\"value\":{\"amount\":0,\"currency\":\"GBP\",\"formatted\":\"£0.00\"}}},\"timestamps\":{\"created_at\":\"2019-07-04T11:12:23Z\",\"updated_at\":\"2019-07-04T11:12:23Z\"}},\"relationships\":{\"cart_item\":{\"data\":{\"type\":\"cart_item\",\"id\":\"a498b15a-2cc7-49ea-93b3-22143bb403ac\"}}}}]}}", "payload": { "data": { "type": "order", "id": "1d67160d-dacb-43ed-80ef-c3c4e7ddf764", "status": "complete", "payment": "paid", "shipping": "unfulfilled", "customer": { "name": "Ron Swanson", "email": "ron.swanson@moltin.com" }, "shipping_address": { "first_name": "Jack", "last_name": "Macdowall", "phone_number": "123456789", "company_name": "Macdowalls", "line_1": "Second Floor, British India House", "line_2": "15 Carliol Square", "city": "Newcastle upon Tyne", "postcode": "NE1 6UF", "county": "Tyne and Wear", "country": "GB", "instructions": "Leave in porch" }, "billing_address": { "first_name": "Jack", "last_name": "Macdowall", "company_name": "Macdowalls", "line_1": "Second Floor, British India House", "line_2": "15 Carliol Square", "city": "Newcastle upon Tyne", "postcode": "NE1 6UF", "county": "Tyne and Wear", "country": "GB" }, "links": {}, "meta": { "display_price": { "with_tax": { "amount": 10000, "currency": "GBP", "formatted": "£100.00" }, "without_tax": { "amount": 10000, "currency": "GBP", "formatted": "£100.00" }, "tax": { "amount": 0, "currency": "GBP", "formatted": "£0.00" } }, "timestamps": { "created_at": "2019-07-04T11:12:23Z", "updated_at": "2019-07-04T11:12:23Z" } }, "relationships": { "items": { "data": [ { "type": "item", "id": "395763ee-1878-4aa0-a7a2-8d4877310d6b" } ] } } }, "included": { "items": [ { "type": "order_item", "id": "395763ee-1878-4aa0-a7a2-8d4877310d6b", "quantity": 1, "product_id": "4f28f222-aa5b-442c-9ce9-c223dc7cf15a", "name": "Spam Fritters", "sku": "spam-fritters-0716", "unit_price": { "amount": 10000, "currency": "GBP", "includes_tax": false }, "value": { "amount": 10000, "currency": "GBP", "includes_tax": false }, "links": {}, "meta": { "display_price": { "with_tax": { "unit": { "amount": 10000, "currency": "GBP", "formatted": "£100.00" }, "value": { "amount": 10000, "currency": "GBP", "formatted": "£100.00" } }, "without_tax": { "unit": { "amount": 10000, "currency": "GBP", "formatted": "£100.00" }, "value": { "amount": 10000, "currency": "GBP", "formatted": "£100.00" } }, "tax": { "unit": { "amount": 0, "currency": "GBP", "formatted": "£0.00" }, "value": { "amount": 0, "currency": "GBP", "formatted": "£0.00" } } }, "timestamps": { "created_at": "2019-07-04T11:12:23Z", "updated_at": "2019-07-04T11:12:23Z" } }, "relationships": { "cart_item": { "data": { "type": "cart_item", "id": "a498b15a-2cc7-49ea-93b3-22143bb403ac" } } } } ] } }, "configuration": { "secret_key": "secret_squirrel", "url": "https://webhook.url" } } ``` ### Example: Deleted resources payload When resources are deleted and you observe an event, you receive a payload which **only** contains the resource type and ID. ```javascript { "id": "c138854a-5311-4543-a368-01e099f5519b", "triggered_by": "product.deleted", "attempt": 1, "integration": { "id": "4596d5e1-26b6-444a-964d-2b6ec46477fd", "integration_type": "webhook", "name": "Product deleted notification", "description": "Let me know when products are deleted from my store." }, "resources": { "id": "a34a378b-2c39-41e4-a240-6b7e65f5bb55", "type": "product" }, "payload": { "type": "product", "id": "a34a378b-2c39-41e4-a240-6b7e65f5bb55" }, "configuration": { "secret_key": "secret_squirrel", "url": "https://webhook.url" } } ``` ### Message Queue Services The payload of messages delivered to your message queue contains information about the fired event. The information takes the form of a standard cloud event. The following table defines the payload attributes and types: | Attribute | Type | Description | | :-------------- | :------------------------------- | :---------------------------------------------------------------------- | | `id` | `string` | A unique ID for this event. | | `integrationid` | `string` | The ID of the integration being fired. | | `type` | `string` | The [observable event](#observable-events) that triggered this event. | | `data` | `object` | The resource affected by this event. | #### Example: Typical payload The following example payload [observes](#observable-events) the `cart.updated` event. The configured queue receives the following message payload: ```javascript { "data": { "description": "", "id": "a-cart-id", "links": { "self": "https://epcc-integration.global.ssl.fastly.net/v2/carts/a-cart-id" }, "meta": { "display_price": { "discount": { "amount": 0, "currency": "USD", "formatted": "$0.00" }, "tax": { "amount": 0, "currency": "USD", "formatted": "$0.00" }, "with_tax": { "amount": 200, "currency": "USD", "formatted": "$2.00" }, "without_tax": { "amount": 200, "currency": "USD", "formatted": "$2.00" } }, "timestamps": { "created_at": "2021-05-17T11:30:07Z", "expires_at": "2021-05-24T11:31:08Z", "updated_at": "2021-05-17T11:31:08Z" } }, "name": "Cart", "relationships": { "customers": {}, "items": { "data": [ { "id": "4d28bc2b-9db3-4c96-801b-df0ac5b41552", "type": "custom_item" } ] } }, "type": "cart" }, "datacontenttype": "application/json", "id": "9a21fb54-6c3b-432a-bade-82a60da6b59a", "integrationid": "e17db0d8-467b-4bf3-9c26-3dfe8b96e9d7", "source": "https://epcc-integration.global.ssl.fastly.net", "specversion": "1.0", "storeid": "b33e328f-31a8-4d57-b0a3-ebf1039b3756", "type": "cart.updated" } ``` ### Example: Deleted resources payload When resources are deleted, and you observe an event, the resource delivered in the message only contains the resource type and ID. ```javascript { "data": { "id": "a2733958-1273-4385-9a05-f1ca7684f760", "type": "product" }, "datacontenttype": "application/json", "id": "efca76df-9fc1-4434-ba26-82339d9b723c", "integrationid": "e17db0d8-467b-4bf3-9c26-3dfe8b96e9d7", "source": "https://epcc-integration.global.ssl.fastly.net", "specversion": "1.0", "storeid": "b33e328f-31a8-4d57-b0a3-ebf1039b3756", "type": "product.deleted" } ``` ### Observable Events You can pass multiple observable keys to the `observes` field of the [integration object](/docs/api/integrations/create-integration), or you can create individual events. You can use an array when you handle multiple webhooks at the same URL. Entity/Resource Action Observable Key Store/Organization Address Created address.created Store Updated address.updated Store Deleted address.deleted Store Account Created account.created Store Updated account.updated Store Deleted account.deleted Store Account Member Created account-member.created Store Updated account-member.updated Store Deleted account-member.deleted Store Account Membership Created account-membership.created Store Updated account-membership.updated Store Deleted account-membership.deleted Store Carts Updated cart.updated Store Deleted cart.deleted Store Currency Created currency.created Store Updated currency.updated Store Deleted currency.deleted Store Customer Created customer.created Store Updated customer.updated Store Deleted customer.deleted Store Custom API Entries Created customAPIEntryType.created Store Updated customAPIEntryType.updated Store Deleted customAPIEntryType.deleted Store File Created file.created Store Deleted file.deleted Store Integration (events) Created integration.created Store, Organization Updated integration.updated Store, Organization Deleted integration.deleted Store, Organization One-Time Password Token Request Created one-time-password-token-request.created Store Order Events Checkout Created order.created Store Payments Updated order.updated / order.paid. The event order.paid is triggered when the payment status is paid. The event order.updated is triggered when the order is captured, completed, refunded, anonymized, or updated. Store Authorized order.authorized Store Orders Fulfilled order.fulfilled Store Canceled order.cancelled Store Capture Transaction Paid order.paid. The event order.paid is triggered when the order status is completed and captured, and the payment status is paid. Store Captured order.updated. The event order.updated is triggered when the order is captured, completed, refunded, anonymized, or updated. Store Refund Transaction Refunded order.refunded Store Payment Gateway Updated payment-gateway.updated Store Catalog releases Created catalog-release.created Store, Organization Updated catalog-release.updated Store, Organization Deleted catalog-release.deleted Store, Organization Catalog rules Created catalog-rule.created Store Updated catalog-rule.updated Store Deleted catalog-rule.deleted Store Settings Created settings.created Store Updated settings.updated Store Stock Transaction Created stock-transaction.created Store Transaction Created transaction.created Store Updated transaction.updated Store Tax Items Updated cart.updated Store Subscriptions You can integrate Subscriptions with external systems like enterprise resource planning, fulfilment and other systems. For example, when a subscriber updates their address, the Customer Relationship Management system is updated with the change. See Subscriptions. User Authentication Info Created user-authentication-info.created Store Updated user-authentication-info.updated Store Deleted user-authentication-info.deleted Store :::note Store-level events contain `store_id` and `org_id` whereas, organization-level events contain only `org_id`. ::: Security Scheme Type: http HTTP Authorization Scheme: bearer --- ## Integrations Setting up and managing integrations. ```mdx-code-block import DocCardList from '@theme/DocCardList'; import {useCurrentSidebarCategory} from '@docusaurus/theme-common'; ``` --- ## List jobs for integration import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Returns the jobs for the given integration UUID. Request --- ## List logs for integration import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Returns the logs for the given integration UUID. Request --- ## List integrations import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Returns a list of all integrations created by the store. --- ## List logs for the job import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Returns the integration logs for the given integration and job UUID. Request --- ## List logs for all integrations for the store import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Returns all integration logs for the store. --- ## Update an integration import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Updates the Integration for the given UUID. Specify whichever attributes you want to change. The values of the other attributes remain the same. If the attributes section is empty, the integration is not updated. Request --- ## Get a Merchant Realm Mapping import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Get a Merchant Realm Mapping Request --- ## Get the Merchant Realm Mapping for the current store import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; This API is used to obtain an [Authentication Realm](/docs/api/single-sign-on/authentication-realms) if there is none yet for the current store. --- ## Merchant Realm Mappings Introduction import ApiLogo from "@theme/ApiLogo"; import Heading from "@theme/Heading"; import SchemaTabs from "@theme/SchemaTabs"; import TabItem from "@theme/TabItem"; import Export from "@theme/ApiExplorer/Export"; The Merchant Realm Mapping object is used to locate the [Authentication Realm](/docs/api/single-sign-on/authentication-realms) which administrators use to sign in to a store via single sign-on. When supplied in the mapping, the prefix field is used during authentication to determine the appropriate authentication realm to sign in with. Security Scheme Type: http HTTP Authorization Scheme: bearer Contact Elastic Path: [support@elasticpath.com](mailto:support@elasticpath.com) URL: [https://www.elasticpath.com](https://www.elasticpath.com) License MIT --- ## Update a Merchant Realm Mapping import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Update a Merchant Realm Mapping Request --- ## Gateways ```mdx-code-block import DocCardList from '@theme/DocCardList'; import {useCurrentSidebarCategory} from '@docusaurus/theme-common'; ``` --- ## Get a Gateway import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Retrieves the specified gateway. Request --- ## Get all Gateways import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Retrieves all gateways. --- ## Payment Gateways Introduction import ApiLogo from "@theme/ApiLogo"; import Heading from "@theme/Heading"; import SchemaTabs from "@theme/SchemaTabs"; import TabItem from "@theme/TabItem"; import Export from "@theme/ApiExplorer/Export"; Payments for orders are processed through a payment gateway. Composable Commerce offers integrations for a selection of payment gateway providers, or you can create your own integrations. Payment transactions are processed similarly for all gateways: 1. A payment transaction is created and an attempt to pay is made. 2. The transaction is forwarded to the third-party gateway specified by the customer. 3. The payment is processed by the third-party gateway. Payment transactions are always processed outside of Composable Commerce for security reasons. Typically, you use a token rather than pass the card details directly. If, however, you want to pass the cart details directly to the third-party provider, Composable Commerce enforces the use of the secure HTTPS protocol. If the transaction is successful, a `200 OK` response is returned. Use the response (success or failure) to update the transaction, which automatically updates the order and payment statuses. A payment transaction can also be refunded. You can select which way you want to process refunds: - Mark as Refunded: You can use your payment gateway’s console to process a refund. Process the refund first in the payment gateway and then use the **Mark as Refunded** capability in Composable Commerce to complete the process. - Refund through Composable Commerce: Start a full or partial refund to a supported payment provider directly from Commerce Manager or the API. You still have the ability to mark as refunded for a pre-integrated gateway, such as Stripe. :::info For nonce-based Authorize.net transactions, if a refund is requested before the transaction has settled (typically within 24 hours), the transaction will be voided instead of refunded. This behavior is specific to nonce-based payments. ::: :::caution Configure your store to use [Manual Gateway](/docs/api/payments/update-manual-gateway) to process payments if the order total is zero or the payment is through non-supported payment providers. ::: ### Order Status Workflow The following image shows the workflow of the order status when you checkout a cart. ![Order Workflow](/assets/Order-Workflow.png) ### Summary of the Workflow 1. [Checkout a cart](/docs/api/carts/checkout). When you checkout a cart, an unpaid order is returned. 2. [Paying for an order](/docs/api/carts/payments). You can process the payment for an order through a payment gateway. You can pay for an order either using purchase payment method or authorize payment method. 3. Confirm the order. Order confirmation might be required when you purchase or authorize a transaction. If you use a purchase method, the order is immediately confirmed. If you use authorize method, funds are captured later when an item is dispatched or restocked, and then the order is considered as complete. See [Capture a Transaction](https://elasticpath.dev/docs/commerce-cloud/payments/transactions/capture-a-transaction). 4. [Fulfill, Refund or Cancel the paid order](/docs/api/carts/refund-a-transaction). The order is considered as fulfilled when it is shipped. You can cancel the order after the checkout or if the order is not fulfilled. You can also choose to refund a partial payment or full payment. 5. (Optional) [Cancel a transaction](/docs/api/carts/cancel-a-transaction). You can cancel or void a pending or authorized transaction. The transaction can be canceled or voided when it is in pending and completed statuses. This works only for Stripe and PayPal and does not work for manual gateway. 6. (Optional) [Anonymize an order](/docs/api/carts/anonymize-orders). You can anonymize an order when it is fulfilled, canceled, or fully refunded. ### Split Payments Split payments involve multiple payment sources for a single order, using externally authorized payments. For example, you can pay for an order using a gift card and a credit card. An order with multiple payment transactions can also be in multiple payment states depending on each transaction. Transactions for split payments are processed similarly for all gateways: 1. A partial payment transaction is created and an attempt to pay the partial amount is made. 2. The transaction for the specified amount is forwarded to the payment gateway specified by the customer. 3. The partial payment is processed. 4. Another partial payment transaction is created and an attempt to pay the remaining amount is made. 5. Another transaction for the remaining amount is forwarded to the payment gateway specified by the customer. 6. The payment is processed, paid, and complete. The payment status must show paid after the order is completed. You can refund transactions for split payments. For more information about refund, see Refund a Payment. The following scenarios show how a shopper can use multiple sources for split payment: - Gift card and credit card - Purchase order and credit card - Store credit and credit card - Employee dollars and credit card - Gift card and loyalty card - Loyalty card and wallet The following image shows a workflow of the split payments. ![Split Payments](/assets/split-payment-workflow.png) The following table describes the payment and order statuses that you can see when an order is passed through multiple stages. | Payment Status | Order Status | Inventory Status | Description | |:-----------------|:-------------|:---------------------|:------------| | `partially_authorized` | `incomplete` | Allocated | Indicates that the payment is partially_authorized and the balance_owing value is greater than zero. In this case, one of the transactions is authorized and complete. | | `partially_paid` | `incomplete` |Allocated | Indicates that the funds are captured but the balance_owing value is greater than zero. In this case, one of the transactions is captured or purchase is complete. | | `unpaid` | `incomplete` | Not Allocated | Indicates that the order does not have any complete payment transactions. In this case, all the transactions or any of the transactions can be still pending. | | `authorized` | `processing` | Allocated | Indicates that completed transactions cover the entire total amount for an order and at least one of the transactions is authorized. | | `paid` | `complete` | Allocated | Indicates that the order is complete and the amount for the order is fully paid when all authorized transactions are captured or purchase transactions are complete. | Contact Elastic Path: URL: [https://elasticpath.com](https://elasticpath.com) --- ## Update Adyen Gateway import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Use this endpoint to configure Adyen. Request --- ## Update Authorize.net Gateway import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Use this endpoint to configure Authorize.net. :::note The credentials used for a test account may differ from those used for a live account. When configuring the payment gateway with your credentials and setting `test` to `true`, the system allows you to test various Authorize.net payment interactions to ensure everything works as expected. Once you are ready to go live, update `test` as `false` to direct requests to the live endpoints instead of the test account. Additionally, ensure that you switch to the credentials for the live account when making this change. To access your sandbox environment, see [Authorize.net Sandbox account](https://developer.authorize.net/hello_world/sandbox.html). ::: Request --- ## Update Braintree Gateway import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Use this endpoint to configure Braintree. Request --- ## Update CardConnect Gateway import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Use this endpoint to configure CardConnect. Request --- ## Update CyberSource Gateway import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Use this endpoint to configure CyberSource. Request --- ## Update Elastic Path Payments Powered by Stripe import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Use this endpoint to configure Elastic Path Payments Powered by Stripe in Commerce. :::note You can contact Elastic Path sales or [customer success team](mailto:customersuccess@elasticpath.com) to get more information about Elastic Path Payments Powered by Stripe and to check whether it will work for you. ::: Request --- ## Update Manual Gateway import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; This endpoint allows you update the manual gateway. Request --- ## Update PayPal Express Checkout import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Use this endpoint to configure PayPal Express Checkout. :::note To learn more about PayPal Express Checkout and check whether it will work for you, contact your sales or [customer success team](mailto:customersuccess@elasticpath.com). ::: Request --- ## Update Stripe Gateway import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Use this endpoint to configure Stripe. Request --- ## Update Stripe Payment Intents Gateway import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Use this endpoint to configure Stripe Payment Intents. Request --- ## Create A Custom API Role Policy import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Create A Custom API Role Policy Request --- ## Custom API Role Policies A Custom API Role Policy defines the level of access a role has to a Custom API. By default, administrative roles like **Store Admin** or **Org Admin** have full access to all Custom APIs. To grant access to other roles, a policy must be created for that specific role and Custom API. Below are the permissions that can be assigned to a role: | Permission | Description | |------------|------------------------------------------| | **Create** | Create a Custom API Entry. | | **List** | Retrieve a list of Custom API Entries. | | **Read** | Get a Custom API Entry. | | **Update** | Update a Custom API Entry. | | **Delete** | Delete a Custom API Entry. | ```mdx-code-block import DocCardList from '@theme/DocCardList'; import {useCurrentSidebarCategory} from '@docusaurus/theme-common'; ``` --- ## Delete a Custom API Role Policy import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Delete A Custom API Role Policy Request --- ## Get a Custom API Role Policy import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Get A Custom API Role Policy Request --- ## Get a Standard Shopper Role import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Get a Standard Shopper Role Request --- ## Get a Standard User Role import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Get a Standard User Role Request --- ## List Custom API Role Policies import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Retrieves a list of Custom API Role Policies ## Filtering The following operators and attributes are available for [filtering](/guides/Getting-Started/filtering) Custom API Role Policies: | Attribute | Operators | Example | |------------------|-------------------------------|----------------------------------------------------------| | `id` | `lt`,`le`,`eq`,`gt`,`ge`,`in` | `eq(id,3fa85f64-5717-4562-b3fc-2c963f66afa6)` | | `created_at` | `lt`,`le`,`eq`,`gt`,`ge` | `ge(created_at,2024-04-29T00:00:00.000Z)` | | `updated_at` | `lt`,`le`,`eq`,`gt`,`ge` | `le(updated_at,2024-04-29T00:00:00.000Z)` | | `custom_api_id` | `eq` | `eq(custom_api_id,fded1d2a-8bb8-48b6-86a5-9eb05cc8626a)` | | `role_id` | `eq` | `eq(role_id,it-developer)` | ## Sorting The following attributes are available for sorting. When specified, the results are sorted in ascending order based on the value of the field. To sort in descending order, prefix the attribute with `-`, for example, `-updated_at`. The default sort order is `created_at` in descending order. - `id` - `created_at` - `updated_at` Request --- ## List Standard Shopper Roles import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Retrieves a list of Standard Shopper Roles --- ## List Standard User Roles import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Retrieves a list of Standard User Roles --- ## Permissions Introduction import ApiLogo from "@theme/ApiLogo"; import Heading from "@theme/Heading"; import SchemaTabs from "@theme/SchemaTabs"; import TabItem from "@theme/TabItem"; import Export from "@theme/ApiExplorer/Export"; A user's permissions are determined by their assigned role, which defines their level of access to APIs and Commerce Manager. These permissions ensure that users can only perform actions and access data relevant to their responsibilities. With [Commerce Extensions](/docs/api/commerce-extensions/commerce-extensions-introduction), you can create Custom APIs to extend the functionality of Commerce. Using Custom API Role Policies, you can specify the permissions for each role, ensuring fine-grained control over who can interact with these Custom APIs. Security Scheme Type: http HTTP Authorization Scheme: bearer Contact Elastic Path: [support@elasticpath.com](mailto:support@elasticpath.com) URL: [https://www.elasticpath.com](https://www.elasticpath.com) License MIT --- ## Standard Shopper Roles Standard Shopper Roles represent the roles of customers. ```mdx-code-block import DocCardList from '@theme/DocCardList'; import {useCurrentSidebarCategory} from '@docusaurus/theme-common'; ``` --- ## Standard User Roles Standard User Roles represent the roles that can be assigned to users through Commerce Manager. These roles define the level of access a user has to Commerce Manager. ```mdx-code-block import DocCardList from '@theme/DocCardList'; import {useCurrentSidebarCategory} from '@docusaurus/theme-common'; ``` --- ## Update a Custom API Role Policy import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Update A Custom API Role Policy Request --- ## Get Personal Data Erasure Request import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; This request serves to get an existing erasure request by its ID. Request --- ## Get all Personal Data Erasure Request import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Gets a list of erasure requests for a specific resource id and resource type. You can use pagination with this resource. For more information, see [pagination](/guides/Getting-Started/pagination). ## Filtering The following operator and attributes are **required** for [filtering](/guides/Getting-Started/filtering) erasure requests. | Operator | Description | |:---------|:-----------------------------------------------------------------------------------------------------| | `eq` | Checks whether the values of two operands are equal. If the values are equal, the condition is true. | | Attribute | Type | Operator | Example | |:----------------| :--- | :--- |:--------------------------------------------------------| | `resource_type` | `string` | `eq` | `eq(resource_type,customer)` | | `resource_id` | `string` | `eq` | `eq(resource_id,0f850c15-d643-480a-a2b4-9e3c26067178\)` | Request --- ## Get Logs Time-to-Live (TTL) Settings import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Get Logs Time-to-Live (TTL) Settings --- ## Get Personal Data Logs import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Gets a list of logs for a specific resource id and resource type. You can use pagination with this resource. For more information, see [pagination](/guides/Getting-Started/pagination). :::note * This request is only accessible to `client_credentials` token users with `Seller Admin`, `Support` and `IT` roles. * Non `client_credentials` token users cannot access this endpoint. See [Permissions](/docs/authentication/tokens/permissions). * This request requires a filter for `resource_type` and `resource_id`. ::: ## Filtering The following operator and attributes are **required** for [filtering](/guides/Getting-Started/filtering) erasure requests. | Operator | Description | |:---------|:-----------------------------------------------------------------------------------------------------| | `eq` | Checks whether the values of two operands are equal. If the values are equal, the condition is true. | | Attribute | Type | Operator | Example | | :---------------- | :--- | :--- | :-------------------------------------------------------- | | `resource_type` | `string` | `eq` | `eq(resource_type,customer)` | | `resource_id` | `string` | `eq` | `eq(resource_id,0f850c15-d643-480a-a2b4-9e3c26067178)` | Request --- ## Get Personal Data Related Data Entries import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Gets a list of related data entries filtered by specific resource id and resource type. You can use pagination with this resource. For more information, see [pagination](/guides/Getting-Started/pagination). :::note * This request is only accessible to `client_credentials` token users with `Seller Admin`, `Support` and `IT` roles. * Non `client_credentials` token users cannot access this endpoint. See [Permissions](/docs/authentication/tokens/permissions). * This request requires a filter for `resource_type` and `resource_id`. ::: ## Filtering The following operator and attributes are **required** for [filtering](/guides/Getting-Started/filtering) erasure requests. | Operator | Description | |:---------|:-----------------------------------------------------------------------------------------------------| | `eq` | Checks whether the values of two operands are equal. If the values are equal, the condition is true. | | Attribute | Type | Operator | Example | | :---------------- | :--- | :--- | :-------------------------------------------------------- | | `resource_type` | `string` | `eq` | `eq(resource_type,customer)` | | `resource_id` | `string` | `eq` | `eq(resource_id,0f850c15-d643-480a-a2b4-9e3c26067178)` | Request --- ## Logs Time to Live Settings You can use the Logs TTL Settings endpoint to retrieve and update settings controlling logs time-to-live (TTL). ```mdx-code-block import DocCardList from '@theme/DocCardList'; import {useCurrentSidebarCategory} from '@docusaurus/theme-common'; ``` --- ## Personal Data Erasure Requests Erasure requests enable you to exercise the right, referred to in regulations such as GDPR, as the right to be forgotten or right to erase. Erasure requests allow you to wipe out personal data from Commerce in an automated way, including: * All related resources (for example, addresses, customers, and so on.) * Personal Data Logs Erasure requests can be created for any data entry in the personal data set (see [Personal Data Concept](/docs/api/personal-data/personal-data-introduction) for details), and the result is the same. :::note Currently, it does not include flows or data external to Commerce. ::: Erasure requests are processed asynchronously. The POST requests return immediately, and processing continues in the background. You can use the GET endpoint to poll for results until you see `{..."status":"SUCCESS"...}` in the response body. In the unlikely event an erasure request fails (if the status is not equal to `SUCCESS`), you are advised to retry by creating another erasure request. If the problem persists, contact Support. :::note Currently, personal data management is only enabled for a limited set of endpoints. See the [personal data concepts page](/docs/api/personal-data/personal-data-introduction) for the list of endpoints that support personal data management. ::: Seller Admin & IT users have full access to Erasure Requests, and Support users have read access. ```mdx-code-block import DocCardList from '@theme/DocCardList'; import {useCurrentSidebarCategory} from '@docusaurus/theme-common'; ``` --- ## Personal Data Introduction import ApiLogo from "@theme/ApiLogo"; import Heading from "@theme/Heading"; import SchemaTabs from "@theme/SchemaTabs"; import TabItem from "@theme/TabItem"; import Export from "@theme/ApiExplorer/Export"; In Commerce, every change to a user’s personal data is logged. Personal data sets are groups of data items that are related to each other. For example, customer, addresses, and authentication information. The contents of a personal data set is dynamic. Data items are attached to each other automatically as they are created or updated. The API allows you to fetch these logs, including the list of related data items. In other words, the data items that belong to the same personal data set. Log entries are kept in the system for a limited time. You can configure the retention period using the Logs Time-to-live (TTL) settings API. The default retention period is 365 days for production store types and 7 days for other store types. ## Personal Data Resource Types | Entity type | Endpoint | Documentation | |-------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------| | customer | `v2/customers/{id}` | [Customers](/docs/customer-management/customer-management-api/customer-management-api-overview) | | account | `v2/accounts/{id}` | [Accounts](/docs/api/accounts/post-v-2-accounts) | | account-member | `v2/account-members/{id}` | [Account Members](/docs/api/accounts/account-members) | | account-membership | `v2/accounts/{accountId}/account-memberships/{id}` | [Account Memberships](/docs/api/accounts/account-membership) | | address | `v2/customers/{customerId}/addresses/{id}`; `v2/accounts/{accountId}/addresses/{id}` | [Addresses](/docs/api/addresses/addresses-introduction) | | user-authentication-info | `v2/authentication-realms/{realmId}/user-authentication-info/{id}` | [User Authentication Info](/docs/api/single-sign-on/user-authentication-infos) | | user-authentication-oidc-profile-info | `v2/authentication-realms/{authenticationRealmId}/user-authentication-info/{userAuthenticationInfoId}/user-authentication-oidc-profile-info/{id}` | [User Authentication OIDC Profile Info](/docs/api/single-sign-on/user-authentication-oidc-profile-infos) | | user-authentication-password-profile-info | `v2/authentication-realms/{authenticationRealmId}/user-authentication-info/{userAuthenticationInfoId}/user-authentication-password-profile-info/{id}` | [User Authentication Password Profile Info](/docs/api/single-sign-on/user-authentication-password-profile-infos) | | order | `v2/orders/{id}` | [Orders](/docs/api/carts/orders) | Security Scheme Type: http HTTP Authorization Scheme: bearer Contact Elastic Path: [support@elasticpath.com](mailto:support@elasticpath.com) URL: [https://www.elasticpath.com](https://www.elasticpath.com) License MIT --- ## Personal Data Logs When a user’s personal data is changed, an event is logged by Commerce. You can use the Personal Data Logs endpoint to access these logs. This API is read only, and you cannot add, update, or delete logs using this API. The API only allows you to read all logs for a particular data entry (specified in the filter GET parameter). :::note Currently, personal data management is only enabled for a limited set of endpoints. See the [personal data concepts page](/docs/api/personal-data/personal-data-introduction) for the list of endpoints that support personal data management. ::: ```mdx-code-block import DocCardList from '@theme/DocCardList'; import {useCurrentSidebarCategory} from '@docusaurus/theme-common'; ``` --- ## Personal Data Related Data Entries This is a supplementary endpoint for the [logs](/docs/api/personal-data/logs-time-to-live-settings) endpoint. It allows you to view all data entries that are related to the resource specified in the filter. For example, a user can get all data items that relate to a customer, such as addresses or user authentication info. This API is read only, and you cannot add, update, or delete anything using this API. The API only allows you to list related data items for a particular data entry (specified in the filter GET parameter). ```mdx-code-block import DocCardList from '@theme/DocCardList'; import {useCurrentSidebarCategory} from '@docusaurus/theme-common'; ``` --- ## Create Personal Data Erasure Request import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; This request serves to create a new erasure request for a given resource ID and Type. All resources that belong to the same personal data set will be erased. Request --- ## Update Logs Time-to-Live (TTL) Settings import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Update Logs Time-to-Live (TTL) Settings Request --- ## Cancel a Job import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Cancels an asynchronous job whose status is pending or processing. Request --- ## Create a Promotion Job import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Use this endpoint to create an asynchronous job to generate codes and export promotion codes. Request --- ## Create a Promotion import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; You can use this endpoint to create the following types of promotion: - Cart Fixed Discount Promotion - Cart Percent Discount Promotion - X for Y Discount Promotion - X for Amount Discount Promotion - Fixed Bundle Discount Promotion - Item Fixed Discount Promotion - Item Percent Discount Promotion - Free Gift Promotion ### The `schema` object Promotions are defined by schemas that are used internally to verify promotions and calculate discounts. You must define a schema when you create the promotion. For more information, see the schema.exclude criteria and the targeting fields criteria. #### The `schema.exclude` criteria When creating a promotion, you can specify when it **should not** be applied. The promotion will not be applied on any cart (or cart item, depending on the promotion type) that fulfills at least one of the `schema.exclude` criteria. The following criteria can be set to exclude items from a promotion: - `schema.exclude.targets` - `schema.exclude.nodes` - `schema.exclude.attributes` - `schema.exclude.conditions` For example, if you want to create a promotion with value as *SKU1* in `schema.exclude.targets` and and color *yellow* and size *small* in `schema.exclude.attributes`, then any products with *SKU1* or the color *yellow* or the size *small* will be excluded from the promotion. To exclude products from a promotion based on multiple conditions at the same time, use `schema.exclude.conditions`. For example, use `schema.exclude.conditions` to exclude items that are both *yellow* in color and *small* in size. #### The targeting fields criteria When creating a promotion, you can also specify when it **should** be applied. To define the targeted products, use the following fields: - `schema.target_catalogs` - `schema.targets` - `schema.target_nodes` - `schema.target_attributes` - `schema.target_conditions` The cart item's catalog is verified if you define the `schema.target_catalogs` field. If the item is in any of the targeted catalogs specified in `schema.target_catalogs`, the promotion will be applied. If the item is not in any of the catalogs, the promotion will not be applied. Then, the cart item is verified to see if it fulfills at least one criteria of any of the four other targeting fields. In other words, the `schema` targeting fields such as `schema.targets`, `schema.target_nodes`, `schema.target_attributes` and `schema.target_conditions` create *OR* targeting conditions. For example, if you create a promotion with values as *SKU1* in `schema.targets` and color *yellow* and size *small* in `schema.target_attributes`, then it will be applied to any products with *SKU1* or the color *yellow* or the size *small*. To create a promotion that targets products based on multiple conditions at the same time, use `schema.target_conditions`. For example, use it to target items that are both *yellow* in color and *small* in size. :::note For Cart Fixed Discount Promotion and Cart Percent Discount Promotion, the cart item's catalog is verified if you define the `schema.target_catalogs` field. If the item is in any of the targeted catalogs specified in `schema.target_catalogs`, the promotion will be applied. If the item is not in any of the catalogs, the promotion will not be applied. ::: :::caution - Line-item discounts are only supported by the line calculation method. For more information about this method, see the Calculation Method section. - Hierarchy-based promotions are not supported for fixed bundle discount promotion and free gift promotion. To promote a bundle, create the bundle in Product Experience Manager, and then create a promotion for that bundle. For more information, see Bundles in Product Experience Manager. - For Free Gift Promotion, we recommend using `auto_add_free_gift` feature with `automatic` setting enabled. When `automatic` is set to `true`, it indicates that promotions are added automatically, and discounts are applied accordingly. If you enable the `auto_add_free_gift`, but do not enable the `automatic` setting, gift items will be added without discounts. In this case, shoppers need to apply coupon codes twice, first to add the gift item and then to apply the discount. ::: Request --- ## Create Promotion Codes import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Use this endpoint to create promotion codes for a specific promotion. :::note When a promotion expires, the promotion codes attached to the promotion automatically become invalid. However, when you re-enable the expired promotion, the promotion codes attached to the promotion are deleted. ::: Request --- ## Delete a Promotion Code import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Use this endpoint to delete a single promotion code. Request --- ## Delete a Promotion import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Use this endpoint to delete a specific promotion. Request --- ## Delete Multiple Promotion Codes import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Use this endpoint to delete multiple promotion codes within a specific promotion. Request --- ## Get a Promotion History import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Use this endpoint to retrieve a promotion history. Request --- ## Get a Promotion import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Retrieves a promotion. Request --- ## Get all Promotions import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Returns all promotions. :::note You can use pagination with this resource. For more information, see [pagination](/guides/Getting-Started/pagination). ::: ### Filtering The following operators and attributes are available when filtering on this endpoint. See [Supported Filtering Characters](https://elasticpath.dev/guides/Getting-Started/filtering#supported-characters). Use `code` filter to search codes within promotions. | Attribute | Type | Operator | Example | |:-----|:---------|:---------|:----------------------------------------| | `code` | `string` | `eq` | `eq(code,some_code)` | For filtering advanced promotion usages, pass the `EP-Public-Search-Type=cm_search` header. Advanced search filtering is only applicable when the promotion code is consumed and the promotion is not deleted. | Attribute | Type | Operator | Example | |:-----|:---------|:---------|:----------------------------------------| | `promo_id` | `string` | `eq` | `eq(promo_id, 69c63c9d-8ccf-44b1-8e98-1e7feebfb581)` | | `promo_name` |`string` | `eq`, `like` | `eq(promo_name,cart percent discount)` | | `promo_type` | `string` | `eq` | `eq(promo_type,fixed_discount)` | | `promo_status` | `string` | `eq` | `eq(promo_status,Running)` | | `promo_checkouts` | `string` | `eq`,`gt`, `ge`, `lt`, `le` | `eq(promo_checkouts,2)` | | `promo_skus_prod_ids` | `string` | `eq`, `like` | `eq(promo_skus_prod_ids, sku1)` | | `promo_start_date` | `string` | `eq`, `gt`, `gr`, `lt`, `le` | `eq(promo_start_date,2023-01-01)` | | `promo_end_date` | `string` | `eq`, `gt`, `gr`, `lt`, `le` | `eq(promo_end_date,2050-06-15)` | | `code_id` | `string` | `eq` | `eq(promo_id,2ea0cd1d-43a9-441b-b03f-3cab84aaee0c):eq(code_id,14b55e6c-3f80-436e-a90a-4de5f0e36240)` | | `code_code` | `string` | `eq`, `like` | `eq(code_code,cart_fixed_10)` | | `code_used` | `string` | `eq`, `gt`, `gr`, `lt`, `le` | `eq(code_used,2)` | | `code_created_date` | `string` | `eq`, `gt`, `gr`, `lt`, `le` | `eq(code_created_date,2023-11-15)` | | `order_id` | `string` | `eq`, `like` | `eq(order_id,ccb13673-627c-4976-88da-f77c542b528f)` | | `order_customer_email` | `string` | `eq`, `like` | `like(order_customer_email,andy*)` | | `order_created_date` | `string` | `eq`, `gt`, `gr`,`lt`, `le` | `le(order_created_date,2023-11-15)` | Request --- ## Get Promotion Code Exported File import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Retrieves exported codes in a CSV format. Request --- ## Get Promotion Codes import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; You can use this endpoint to retrieve promotion codes. :::note - The `codes.max_uses` attribute represents the maximum usage of the codes. - The `codes.uses` attribute represents the remaining number of times the codes can be used for the promotion. - Codes created before April 27, 2023 will only have `codes.uses` attribute in the response body. ::: Request --- ## Get Promotion Jobs import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Retrieves the list of jobs for a specific promotion. In the response example, you can see the `result.generated` field, which indicates the number of codes generated during the job processing. Additionally, you may also see the optional `result.deleted` field, indicating the number of codes deleted during the job cancellation. The parameters and result objects are shown only when `job_type` is `code_generate`. ### Filtering The following operators and attributes are available when filtering on this endpoint. | Attribute | Type | Operator | Example | | ----------| ----- | -------- | ------ | | `job_type` | `string` | `eq` | `eq(job_type, code_export)` | | `status` | `string` | `eq` | `eq(status, complete)` | ### Errors If an error occurs during job processing, the response includes an optional error field. For example, when you `GET` promotion jobs, the following response shows the details within the error field if an error occurred during job processing. ```json \{ "data": [ \{ "type": "promotion_job", "id": "84d86114-a92d-4c34-92f1-3e36ef6cabeb", "promotion_id": "ad386702-e780-42c6-b190-0527ad768917", "job_type": "code_generate", "name": "job", "parameters": \{ "number_of_codes": 1000, "consume_unit": "per_cart", "max_uses_per_code": 1, "code_length": 8, "code_prefix": "promo-" \}, "status": "failed", "error": "codes limit exceeded", "meta": \{ "timestamps": \{ "created_at": "2023-12-06T13:52:29.587Z", "updated_at": "2023-12-06T13:54:49.133Z" \} \} \} ], "links": \{ "current": "https://useast.api.elasticpath.com/v2/promotions/ad386702-e780-42c6-b190-0527ad768917/jobs?page[offset]=0&page[limit]=25", "first": "https://useast.api.elasticpath.com/v2/promotions/ad386702-e780-42c6-b190-0527ad768917/jobs?page[offset]=0&page[limit]=25", "last": "https://useast.api.elasticpath.com/v2/promotions/ad386702-e780-42c6-b190-0527ad768917/jobs?page[offset]=0&page[limit]=25", "prev": "https://useast.api.elasticpath.com/v2/promotions/ad386702-e780-42c6-b190-0527ad768917/jobs?page[offset]=0&page[limit]=25", "next": "https://useast.api.elasticpath.com/v2/promotions/ad386702-e780-42c6-b190-0527ad768917/jobs?page[offset]=0&page[limit]=25" \}, "meta": \{ "page": \{ "limit": 25, "offset": 0, "current": 1, "total": 1 \}, "results": \{ "total": 1 \} \} \} ``` Request --- ## Promotion Codes You can apply promotions automatically to all customer carts, or you can create promotion codes that customers must enter to receive the discount. You can enable this feature by setting the automatic attribute to `false` in the promotions schema when you create a promotion. For more information, see [Create Promotion Codes](/docs/api/promotions/create-promotion-codes). You can generate and export codes for a promotion using the bulk code generation feature, which allows you to create a large number of unique codes and export them in CSV format. For details, refer to the [Generating Bulk Codes](/docs/commerce-manager/promotions-standard/overview#generating-bulk-codes) and [Managing Export Codes](/docs/commerce-manager/promotions-standard/overview#managing-code-export) sections. You can generate a maximum of 1000 codes for a promotion. If you need to generate more than 1000 codes, limit the promotion's duration to a maximum of 365 days from its start date. The promotion expiry date is 365 days. With the consume unit feature, you can limit the number of usages of a code for a promotion. You must create a code for this promotion to track the usage of the promotion. The consume unit options are `per_cart` and `per_item`. For example, consider a store that offers 50% off on *SKU1*, but limits the promotion to a maximum of two usages. Under the `per_cart` setting, a shopper can buy *SKU1* twice in a separate transaction, each at a 50% discount. However, with the `per_item` setting, if a shopper buys two SKU1s in a single purchase, both items count toward the promotion's usage limit. Therefore, the shopper would use up both usages of the promotion in a single purchase. Promotion codes can be group codes or individual codes. For example, you can offer a seasonal discount to all customers, such as *SUMMER-SALE*, or you can offer preferred customers unique discount codes. Promotion codes expire automatically at the end of the promotion period and are removed from the promotion. When a promotion expires, the promotion codes attached to the promotion automatically become invalid. However, when you re-enable the expired promotion, the promotion codes attached to the promotion are deleted. When you checkout a cart with an expired promotion, the expired promotion will be automatically removed from a cart and the checkout process is initiated. As a best practice, we recommend to update your cart to remove the expired promotion before initiating the checkout process. When extending the end date of an expired promotion with over 1000 codes, you will receive an error response. See [Update a Promotion](/docs/api/promotions/update-a-promotion). In such cases, we recommend [duplicating the promotion](/docs/commerce-manager/promotions-standard/overview#duplicating-promotions), allowing you to set the new end dates and create promotion codes as needed. ```mdx-code-block import DocCardList from '@theme/DocCardList'; import {useCurrentSidebarCategory} from '@docusaurus/theme-common'; ``` --- ## Promotion Jobs Use Jobs API to initiate a job within a promotion. Jobs operate asynchronously and have a different status based on their progress. The following are the job statuses: - `pending`: Commerce has received the request but is currently busy processing other requests. - `processing`: Commerce has initiated processing the job. - `completed`: The job is successfully completed. - `failed`: The job has failed. - `cancelling`: The job is currently in the process of being canceled. You need to wait for the cancellation process to complete. This occurs prior to the `cancelled` status. For example, if you cancel a big `code_generate` job, it may take some time for the cancellation to complete since part of the cancellation process involves deleting the generated codes. - `cancelled` : The job request is canceled. ![Promotion Job Statuses Workflow](/assets/job_status_workflow.png) ### Characteristics of Jobs - You can only initiate one job at a time within a promotion. If you want to run another job for the same promotion, you must wait until the previous job is `completed` or `failed`. However, you can create new jobs for different promotions even if there are `pending` jobs in other promotions. - If you intend to manage promotions with more than 10,000 codes per promotion, we recommend [exporting codes](/docs/api/promotions/create-a-promotion-job) for viewing purposes instead of attempting to view them within Commerce Manager. This recommendation is made due to our enforced maximum page offset limit of 10,000. Altering the page_offset_limit value poses potential performance risks to the platform. - A `code_generate` job is initiated even if the maximum allowable number of codes for the promotion has been reached. However, when processed, this job will fail. To view the status of this failed job, you can only do so by passing [GET Jobs](/docs/api/promotions/get-promotion-jobs) request. - A limited number of jobs can be processed at a time. Jobs are queued and processed sequentially, one after the other. You can expect a certain delay before job processing. ```mdx-code-block import DocCardList from '@theme/DocCardList'; import {useCurrentSidebarCategory} from '@docusaurus/theme-common'; ``` --- ## Promotions Standard Introduction import ApiLogo from "@theme/ApiLogo"; import Heading from "@theme/Heading"; import SchemaTabs from "@theme/SchemaTabs"; import TabItem from "@theme/TabItem"; import Export from "@theme/ApiExplorer/Export"; Promotions Standard offer the flexibility to provide different types of discounts to all your customers or specific customers. You can apply promotions automatically to all purchases, or alternatively, create promotion codes that customers must enter to receive a discount. You can have multiple promotions active at the same time. Promotions are active in a fixed duration, with defined start and end dates. However, you can manually stop a promotion at any time. For testing your promotions when scheduling a future date for your shopping cart, you can use the [Preview Cart API](/docs/api/carts/create-a-cart#preview-cart). When [Creating a Free Gift Promotion](/docs/api/promotions/create-a-promotion), set the promotion to automatic and enable the `auto_add_free_gift` feature. This way, the shopper will see the free gift in their shopping cart when the target product is added to the cart, and the discount will be applied. This eliminates the need for an additional step to apply the code for the gift discount. However, if you desire more control over when or how the free gift is added, you can choose to use a promotion code and disable the **Automatically add free gift items to the cart** toggle in Commerce Manager. See [Creating Free Gift Promotions](/docs/commerce-manager/promotions-standard/item-level-promotions/free-gift-promotions). For a seamless process, ensure that the currencies of automatically added gift items match with those of the items that initiate free gifts. Additionally, ensure that the free gift item is within the same catalog as the eligible items. For inventory-managed products, ensure that you have sufficient inventory available to run the promotion. If there is insufficient stock of free gift items for all eligible free products, the free gifts won't be added to the cart. Promotions Standard can be: - [Cart-level promotions](#cart-level-promotions): The promotion applies to the entire cart. - [Item-level promotions](#item-level-promotions): The promotion applies to individual items in a cart. :::note The shipping prices do not impact eligibility for item-level and cart-level promotions. ::: All items in the cart are eligible for cart-level promotions, even if they already have item-level promotions applied. You can select a few products and exclude them from a cart-level promotion. However, the store that uses a simple calculation method does not support promotions with the exclude setting. ### Cart-level Promotions Cart-level promotions are applied to all items in the cart. Cart-level promotions include: - Fixed discount: Reduces the cart total by a fixed amount, such as $5.00 off. - Percentage discount: Reduces the cart total e by a specific percentage, such as 10% off. The following image shows a cart before and after applying a 10% Off promotion. With the discount applied, the price for each item is reduced by 10% and the cart total reflects the reduction. ![Each item in the cart shows a price that is 10% less than the catalog price.](/assets/promotions-cart-10-percent-off.png) All items in the cart are eligible for cart-level promotions, even if they already have item-level promotions applied. You can select a few products and exclude them from a cart-level promotion. However, the store that uses a [simple calculation method](https://elasticpath.dev/guides/How-To/Carts/calculate-totals#simple-calculation-method) does not support promotions with the `exclude` setting. ### Item-level Promotions Item-level promotions are applied to each item that qualifies for the promotion. In a shopping cart, the price of each item reflects the discount applied to each item. With the `max_applications_per_cart` setting, you can limit the number of purchases of an item at the sale price in a cart. For more information, see the Promotions API section. Item-level promotions include the following promotion types: - X for Y: Offers bulk discount based on unit price, such as 2-for-1 sales. - X for amount: Offers a bulk discount based on a fixed price, such as 3-for-$20 sales. - Bundle: Offers bulk discount when selected products are purchased together. For example, Buy any two items from the list for $100. - Item fixed discount: Reduces the price of multiple items by a fixed amount, such as $5.00 off. - Percentage item discount: Reduces the product price for multiple items by a specific percentage, such as 10% off. You can also count the number of usages of the promotion per SKU item and limit the usage of the promotion per item. For example, if the usage of the promotion is limited to ten and the shopper purchases two of the same item and three of the another item, five uses of the promotion is deducted from the total usage limit. - Free Gift: Offers a free item when a specific product or a group of products are purchased. :::caution - Item-level promotions are only supported by the line calculation method. For more information about this method, see the [Calculation Method](/docs/api/settings/settings-introduction#calculation-method) section. - The `max_discount_value` setting specifies the maximum possible discount for the cart. To avoid the conflict with the promotions and the promotion to work, we recommend not to use this setting for the following promotions: - Cart-level fixed discount - Item fixed discount - X for Y discount - X for amount discount - Bundle - Free gift - The `max_applications_per_cart` setting, which specifies the maximum number of applications of a promotion per cart, is applicable to line-item promotions only. For example, in a store that offers *buy SKU1 get a free gift* promotion with maximum application per cart set to one, the buyer can only use the free gift promotion once per cart. If maximum application per cart is not set, the buyer can use the promotion multiple times. You can also set maximum application per cart to zero to remove any usage limit. - The `exclude` array consists of productIDs or SKUs of products to be excluded from the cart-level promotions, such as `fixed_discount` and `percent_discount`. However, the stores that use simple calculation method do not support excluding products from promotions. - Already existing promotions created before September 28, 2022 will not have `created_by` and `updated_by` attributes in their response body. ::: You can create codes for a promotion so that customers receive the discount only when the code is provided. ### Multiple promotions for the same SKU You can have multiple promotions for the same SKU. However, each instance of the SKU in the cart is eligible for only one item-level promotion. :::note The promotions are applied in the order of date of creation of the promotions. The oldest promotion is applied first and the newest promotion is applied last. For each instance of a SKU that matches the criteria in the oldest promotion, the promotion is applied. For the remaining instances of the SKU, each instance is compared to the criteria for the next oldest promotion. ::: For example, a cart consists of 1 *BestEver Coffee Maker* and 2 *BestEver Coffee Grinders*. The following promotions are available and applied automatically without a code: - An existing *BestEver Coffee Maker* + *Grinder* bundle promotion for $200.00. The bundle discount is distributed among the items in the bundle depending on the price of each item. - A newly added *BestEver Coffee Grinders* 10% Off percentage item discount promotion. In this example, *BestEver Coffee Maker* costs $150 and *BestEver Coffee Grinder* costs $100. The promotions work in the following order: 1. The $50 bundle discount is distributed among the items depending on the cost. In this example, the cost proportion of products is 3:2 and the *BestEver Coffee Maker* gets $30 discount and *BestEver Coffee Grinder* gets $20 discount. 2. The second promotion is applied to the remaining *BestEver Coffee Grinders* item, and the price is reduced to $90. 3. The cart total after both discounts is $290 instead of $350. ### Understanding how Promotions work with Bundles #### Discounting Promotion Bundles Bundles offer a bulk discount when selected products are purchased together. For example, for a bundle promotion, (SKU1 or SKU2 ) + SKU3, the promotion is applied if the bundle includes either SKU1 and SKU3 or SKU2 and SKU3. This setup encourages the purchase of multiple items together at a discounted rate. #### Discounting Product Bundles via promotions For both Cart-level promotions and Item-level promotions, discounts are applied at the bundle level that can have fixed bundle price or automatic/cumulative pricing. It is important to note that promotions do not apply to components within a bundle even if the individual item within the components qualifies for promotion. See the following examples: - **Example 1**: Consider that Playtend Games offers a bundle that includes a game console, the Playtend Invaders Game, and the Invaders Controller. If there is an existing Item Percent Discount for the Playtend Invaders Game when sold separately, this discount will not apply when the game is part of the bundle. This ensures that the bundle pricing strategy is maintained. - **Example 2**: In the case of Attribute-based promotions, consider a bundle that consists of *Item A* with attribute *Brand A* and *Item B* with attribute *Brand B*. If *Item A* with attribute *Brand A* qualifies for Item Percent Discount promotion, this discount is not applied to the bundle since the *Item A* is a component item within the bundle. To learn how to create a bundle, see [Create a Bundle](/docs/api/pxm/products/create-product). ### Condensed Promotion A condensed promotion is essentially an object that contains specific meta information about a promotion applied to the cart or order. Condensed promotions can be retrieved from the following endpoints: - [Get a Cart](/docs/carts-orders/Includes#get-retrieve-promotions-from-a-cart): This endpoint displays cart-level condensed promotions within the included object. If `?include=items` is specified, the included object also contains cart item-level promotions. The relationships field at the cart level has a promotions section only when `?include=promotions` is specified. - [Get Cart Items](/docs/carts-orders/Includes#get-retrieve-promotions-from-cart-items): This endpoint shows both cart-level and item-level discounts in a condensed format within the included object. - [Get an Order](/docs/carts-orders/Includes#get-retrieve-promotions-from-an-order): This endpoint displays order-level condensed promotions within the included object. - [Get Order items](/docs/carts-orders/Includes#get-retrieve-promotions-from-order-items): This endpoint displays both order-level and item-level promotions in the included object. This applies to both Promotions Standard and [Rule Promotions](/docs/promotions-builder/overview). Security Scheme Type: http HTTP Authorization Scheme: bearer Contact Elastic Path: URL: [https://elasticpath.com](https://elasticpath.com) License MIT --- ## Promotions Standard ```mdx-code-block import DocCardList from '@theme/DocCardList'; import {useCurrentSidebarCategory} from '@docusaurus/theme-common'; ``` --- ## Update a Promotion import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Use this endpoint to update a specific promotion. :::note You can re-enable an expired promotion by updating the end date to a future date. However, when you enable a promotion again, all codes previously attached to it are deleted to make sure that duplicate promotion codes do not exist on different promotions. ::: ### Errors When extending the end date of an expired promotion with over 1000 codes, you will receive the following error response. In such cases, we recommend duplicating the promotion, allowing you to set the new end dates and create promotion codes as needed. ```json { "errors": [ { "status": 422, "source": "request", "title": "Unprocessable Entity", "detail": "" } ] } ``` Request --- ## Anonymize Rule Promotion Usages import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Anonymizes user-related data in Rule Promotion usage records. This operation is typically used for GDPR compliance or privacy-related requests. - This process replaces identifiable user data with anonymized placeholders. - Affects all recorded promotion usages where customer data is stored. - Does not impact historical transaction records or applied discounts. A successful request returns a `200 OK` response with the anonymized usage records. Request --- ## Cancel a Rule Promotion Job import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Cancels an asynchronous job for a rule promotion if its status is `pending` or `processing`. - Only jobs that have not yet completed can be canceled. - Once canceled, no further processing occurs, and partially completed results may be deleted. Request --- ## Create Rule Promotion Codes import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Creates new promotion codes for a specific rule promotion, allowing customers to redeem discounts based on predefined conditions. - Supports bulk creation of multiple promotion codes in a single request. - Each code can have individual usage limits. - Can optionally assign codes to specific users to enforce targeted promotions. - The promotion codes are case-insensitive. :::note Regarding first time shopper limitations: - Orders without payment transactions do not count as completed purchases. - Canceling or refunding an order does not reinstate first-time shopper status. - A first-time shopper coupon code cannot have limited uses or be assigned to specific users, meaning the code cannot be restricted by the number of times it can be used or tied to a specific customer ID. ::: A successful request returns a `201 Created` response with details of the generated promotion codes. ### Duplicate Codes Duplicate promotion codes **are supported across different promotions** in the store, regardless of their statuses and validity dates. However, **duplicate codes cannot be created within the same promotion**. This means that shoppers can apply a single coupon code to trigger multiple promotions if those promotions share common coupon codes. Codes that share the same name can serve different purposes. For example, one code may have `per_application` with a limited number of uses, while another identical code can have `per_checkout` with unlimited use. **Duplicate Code Handling:** - If a duplicate code is detected **within the same promotion**, the request will return a `422 Duplicate code` error. - When creating duplicate codes, a message appears with the successful response indicating the duplication. Please refer to the **OpenAPI examples** section on this page for sample request structures. Request --- ## Create a Rule Promotion Job import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Creates an asynchronous job for a specific Rule Promotion. Jobs are used to generate or export promotion codes in bulk. The following job types are supported: - **`code_generate`**: Generates a batch of unique promotion codes. - **`code_export`**: Exports all existing promotion codes as a downloadable CSV file. Job processing occurs asynchronously. The job request is queued, and its status must be checked separately. ### Job Processing Status Jobs can have the following statuses: - `pending`: Job is in the queue, waiting to be processed. - `processing`: Job is actively being processed. - `completed`: Job completed successfully. - `failed`: Job encountered an error and did not complete. - `cancelling`: Cancellation in progress (for long-running jobs). - `cancelled`: Job was successfully cancelled. Please refer to the **OpenAPI examples** section on this page for sample job creation requests. Request --- ## Create a Rule Promotion import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Creates a new rule-based promotion, allowing flexible discount strategies based on cart or item conditions. Promotions can apply fixed or percentage-based discounts, apply automatically or via codes, and have eligibility rules based on product attributes, cart total, SKU conditions, custom attributes, and more. This endpoint supports a variety of promotion types, such as: - **Cart-wide discounts** - **Item-specific discounts** - **Shipping discounts** - **Combinations thereof** :::note The minimum item discount amount is zero, both for amounts and percentages. A store can have a maximum of **50 active and future automatic rule promotions**. ::: Request --- ## Delete Rule Promotion Codes import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Deletes one or more promotion codes from a specific rule promotion. - Supports **bulk deletion**, allowing multiple codes to be removed in a single request. - Removes promotion codes permanently, making them unavailable for future use. - If a code has already been redeemed, it will be removed from the system but may still reflect in historical transactions. A successful request returns a `204 No Content` response, indicating the specified promotion codes have been deleted. Request --- ## Delete a Rule Promotion import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Deletes an existing Rule Promotion identified by its promotion ID. - This action **permanently removes** the promotion and cannot be undone. - If the promotion is active, please ensure that its removal does not impact ongoing campaigns. A successful request returns a `204 No Content` response, indicating that the promotion has been deleted. Request --- ## Delete A Single Rule Promotion Code import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Deletes a single promotion code from a specific rule promotion. - Permanently removes the specified promotion code, making it unavailable for future use. - Can be used to **revoke a specific code** without affecting other codes under the same promotion. - If the code has already been redeemed, it will still be removed from the system but may still reflect in historical transactions. A successful request returns a `204 No Content` response, indicating the specified promotion code has been deleted. Request --- ## Get a Rule Promotion by ID import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Retrieves a single Rule Promotion by the promotion ID. Responses include promotion specifications such as discount type, eligibility criteria, and configuration details. Request --- ## Get Rule Promotion Code Usages import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Retrieves a list of usage records for a specific Rule Promotion code. - Provides insights into how many times a specific code was used. - Can be filtered and paginated to refine results. - Useful for tracking the performance of individual promotion codes. Request --- ## Get Rule Promotion Codes import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Retrieves the list of promotion codes associated with a specific Rule Promotion. - Returns all codes generated for the given promotion ID, including details on usage limits and redemption status. - Supports both automatically generated and manually created promotion codes. - Can be used to verify whether a promotion code is still valid or has reached its usage limit. Request --- ## Get Rule Promotion Code Exported File import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Retrieves the exported promotion codes for a rule promotion job in a CSV format. - The file contains the generated codes along with relevant metadata. - This endpoint is applicable only for jobs of type `code_export`. - The job must be in a `completed` state before the file can be retrieved. Request --- ## Get Rule Promotion Jobs import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Retrieves a list of jobs associated with a specific rule promotion. Each job represents an asynchronous operation such as promotion code generation or export. The response includes details such as: - **Job type** (`code_generate` or `code_export`) - **Job status** (`pending`, `processing`, `completed`, `failed`, `cancelling`, or `cancelled`) - **Parameters used** (such as number of codes generated) - **Results** (such as number of codes successfully generated or deleted) ### Filtering You can filter jobs by: - **Job Type** (`eq(job_type, code_export)`) - **Status** (`eq(status, complete)`) Request --- ## Get Rule Promotion Usages import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Retrieves a list of usage records for a specific Rule Promotion. - Provides details about when and how a promotion was used. - Can be filtered and paginated to refine results. - Useful for analyzing promotion effectiveness and customer engagement. Request --- ## Get Rule Promotions import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Retrieves a list of rule-based promotions, including information such as discount type, eligibility criteria, and configuration details. This endpoint supports filtering to refine results based on specific promotion attributes. Use query parameters to filter promotions by: - **Code** – Retrieve a specific promotion by its code. - **Promotion name** – Search for promotions by name. - **Activation status** – Filter by whether a promotion is active or not. - **Stackability** – Identify promotions that can or cannot be combined with others. - **Start and end dates** – Retrieve promotions based on their validity periods. Request --- ## Rule Promotions API import ApiLogo from "@theme/ApiLogo"; import Heading from "@theme/Heading"; import SchemaTabs from "@theme/SchemaTabs"; import TabItem from "@theme/TabItem"; import Export from "@theme/ApiExplorer/Export"; Rule Promotions provide the flexibility to offer diverse discounts to shoppers. This functionality supports discounts of varying complexities, from code-based customer discounts, to "Buy X Get Y" scenarios, fixed price promotions, and more based on your business needs. You can create a Rule Promotion using the Rule Promotions API or through the Promotions Builder in Commerce Manager. To apply Rule Promotions in carts and orders across an entire store, please enable the `use_rule_promotions` configuration in Cart Settings. You can also update a specific cart to use Rule Promotions by updating the cart's specific discount settings. Please see [Update A Cart](/docs/api/carts/update-a-cart) for more details. Enabling Rule Promotions enacts Hybrid Mode, allowing simultaneous use of both Promotions Standard and Rule Promotions discounts. For example, let's say a store provides the following promotions: - A Promotions Standard discount for 10% off the shopping cart - A Rule Promotion offering for a 20% discount on the shopping cart If a cart qualifies for both discounts based on the respective eligibility criteria, the system applies both types of discounts to the shopping cart, starting with Promotions Standard definitions before applying Rule Promotions. In this case, the application results in a 10% discount from the Promotions Standard definition and a 20% discount from the Rule Promotion. ### Rule Set A rule set is the criteria that determine when and how promotions get applied. Rule Sets consist of rule conditions and corresponding actions, which define eligibility and application details, respectively. Rule Sets may also contain targeted catalogs and currencies for further application granularity. **Example** Buy an apple, get an orange 50% off. Here, buying an apple is the rule and the 50% discount on an orange is the action. #### Rules Rules describe the conditions necessary for promotion eligibility. In our apple-orange example above, the rule indicates the shopper must buy an apple to get the discount on an orange. In other words, the buying of an apple is the condition which determines eligibility for the corresponding discount. **Condition Architecture:** All conditions follow a consistent structure with three primary components: - **`strategy`**: Defines the type of condition (e.g., `cart_total`, `item_category`) - **`operator`**: Specifies how the condition is evaluated (e.g., `gte`, `in`, `contains_all`) - **`args`**: Contains the values to evaluate against Some conditions support additional components for complex scenarios: - **`children`**: Sub-conditions that provide additional specificity - **`condition`**: Used in actions to define item-specific restrictions **Condition Categories:** - **Cart-level**: Evaluate entire cart properties (total, custom attributes) - **Account-level**: Consider customer account characteristics (tags, segments) - **Item-level**: Target specific products, categories, or attributes - **Bundle conditions**: Complex multi-item requirements for "Buy X, Get Y" scenarios - **Logical operators**: AND/OR logic for sophisticated eligibility rules **Key Design Considerations:** - **Performance**: Order conditions from most to least restrictive for optimal evaluation - **Maintainability**: Use `item_identifier` instead of legacy `item_sku`/`item_product_id` strategies - **Complexity**: Limit nesting depth and consider evaluation costs for complex bundle conditions - **Business Logic**: Ensure condition combinations align with promotion goals and margin requirements #### Actions Actions describe how discounts apply to eligible carts and orders. These signify the discount type, level, configurations, and any limitations or restrictions when applying. Actions can also include: - Action conditions: specify which items should be included or excluded when applying the discounts. These can be based on factors such as item SKUs, product attributes, quantities, or categories. - Action limitations: impose restrictions on the number of products eligible for discounts, maximum discount amounts, and/or total applications for discounts. In the apple-orange example, the action denotes the system applies a 50% discount to an orange, assuming the eligibility rules are met. For more complex scenarios, the action might say to provide a 50% discount on up to three oranges or might provide a fixed $1 discount on the two most expensive items from the "fruit" category. :::note For promotions that include a mix of item and cart rules or actions, we recommend including the specific item conditions in all item strategies to ensure desired discount applications. For complex promotions in general, we recommend including specific item conditions on all item strategies to ensure the appropriate items receive discounts. Please see the [Create a Rule Promotion API Request Examples](/docs/api/promotions-builder/create-rule-promotion) for more details on specifying conditions, restrictions, and inclusions. ::: #### Action Limitations Action limitations define constraints or rules that govern how a promotion's action is applied. While actions specify what discount is given (e.g., 10% off the cart), limitations control how much, to which items, and under what circumstances that action is applied. Limitations include: - **`max_discount`**: Caps the total value of the discount. - **`max_quantity`**: Limits the number of discounted units per item. - **`items`**: Restricts how many and which items are eligible, and in what order (e.g., max_items, price_strategy). - **`max_items`**: Specifies the maximum number of items eligible for the discount. - **`price_strategy`**: Determines how eligible items are selected based on price: - **Cheapest (default)**: The discount is applied to the cheapest item(s) in the cart. - **Expensive**: The discount applies to the most expensive item(s) in the cart. Some limitations, like auto_add, influence the application behavior of the action rather than its scope. - **`auto_add`**: Automatically adds items to the cart once conditions are met, providing additional configuration for the promotion’s application mode. - **`show_suggestions`**: A flag indicating whether to show suggestions for eligible items in the cart if the item is not in the cart. In this way, limitations can affect either the scope of the discount or the manner in which it is applied, providing both technical and user-facing boundaries around a promotion’s behavior. For example, consider a **50% discount on items from a category**, with the following limitations: - **Applies to a maximum of two items (`max_items: 2`)** - **Only applies to the two cheapest eligible items (`price_strategy: cheapest`)** - **Limits the total discount to $10 (`max_discount: 1000`)** - **Ensures a maximum of two units per eligible item receive the discount (`max_quantity: 2`)** #### Catalogs and Currencies As part of the Rule Set, you can also specify the catalogs and currencies for a given Rule Promotion. With catalogs defined, the promotion only considers items from the identified catalogs and therefore will not consider custom items or items from other catalogs. With no catalogs defined, the promotion considers all items, including custom items. Specifying a currency for a Rule Promotion restricts it to carts using that currency. Rule Promotions support multiple currencies when using a percent discount. If no currencies are defined, the discount applies to carts in any currency. ### Building Blocks #### Strategies Strategies describe the types of condition criteria or application actions used to build a promotion. A given promotion can be comprised of several strategies in its rules and actions. These might include several instances of similar strategies, different strategies, or some combination thereof. Think of these as building blocks that can be applied together to provide a functional discount. - Rule strategies define the types of conditions that need to be met for eligibility. These might include cart total amount, item prices, cart custom attributes, and more. - Action strategies refer to the type of action execution run when the eligibility criteria are met. For actions, the possible strategies are `cart_discount`, `item_discount`, `item_bundle_discount` and `shipping_discount`. For more information, please see [Promotions Builder API Overview](/docs/promotions-builder/promotions-builder-api/promotions-builder-api-overview). #### Operators and Args Operators determine how to evaluate a given strategy, while `args` define the value threshold to measure against. For example, please consider the following condition strategy: ``` { "strategy": "cart_total", "operator": "gte", "args": [ 10000 ] } ``` In this example, the strategy is `cart_total`, telling the system to assess eligibility based on the total cart value. The operator is a greater-than-or-equal-to (`gte`) evaluation, indicating the candidate value (in this case, cart total) becomes eligible once it reaches or exceeds the threshold. Finally, the `args` value provides the threshold value to compare against, 10000. Taken together, then, this strategy looks for cart totals greater than or equal to 10000. ::: note Different strategies support different operators. For more information, please see [Rule Promotions API Overview](/docs/promotions-builder/promotions-builder-api/promotions-builder-api-overview). ::: #### Children and Sub-Conditions For additional promotion granularity, some strategies support additional specifications via `children` and `condition` fields. These fields contain strategies, which provide further specifications around their parent strategy evaluations. In other words, sub-conditions refer to additional criteria or conditions that must be met for a particular promotion to be applied. The following strategies support children/sub-conditions: - `item_price` - `item_quantity` - `item_category` - `item_attribute` - `and` - `or` Notably, when multiple sub-condition siblings exist, they are combined together, such that all sub-conditions must be met to fulfill eligibility. ### Stacking Promotion stacking and priority are key elements in managing discounts, ensuring promotions are applied as intended. Stacking allows multiple promotions to be applied to a single cart, either targeting the same items or different ones. The `stackable` flag determines whether a promotion can stack with others, defaulting to `true`. If set to `false`, no other promotion can stack on top, and the highest-priority promotion takes precedence. Priority settings dictate the order in which promotions are applied, with higher numbers indicating higher priorities. By default, promotions without assigned priorities are applied in reverse order of creation, with newer promotions applied first and calculated against any existing discounted prices. Hybrid Mode enables the coexistence of Standard Promotions and those configured in the Promotions Builder, with each functioning independently. This means Standard Promotions can stack alongside non-stackable Builder promotions, and their stackability and priority settings remain unaffected by Standard Promotions. Override stacking, set using the `override_stacking` flag, provides an additional layer of control over how promotions interact. This flag determines whether the promotion can stack with other promotions that are typically non-stackable and defaults to `false` when not set. When set to `true`, the promotion can stack with promotions configured as non-stackable, unless those non-stackable promotions also override stacking. ### Shipping Rule Promotions support shipping discounts, identified by the corresponding strategies during promotion creation. Shipping discounts apply to shipping group base prices and do not impact shipping taxes or configured shipping fees. Please see [Shipping Groups](/docs/ship-groups/shipping-groups/index) for more information on creating and interacting with shipping groups. ### Items Bundle You can promote and discount groups of items together using the `items_bundle` rule strategy and the `items_bundle_discount` action strategy. When these strategies are applied, the cart must contain items that meet all specified criteria to qualify for the discount. - The `items_bundle` rule strategy defines the required group of items for discount eligibility. - The `items_bundle_discount` action strategy specifies how the discount is applied to the qualifying group. - The `items_bundle` strategy requires **at least one** requirement that defines which items are eligible. Bundle items can be mixed across categories or attributes to form a valid bundle. - The `item_quantity` can be used with any of the bundling strategies, including `item_category`, `item_identifier`, `item_attribute`, etc. - `item_quantity` only support `eq` operator when configuring `items_bundle` strategy. - For instance, targeting a category with `item_quantity` with operator `eq` 2 means any two items from that category can form a bundle. The system will prioritize individual line items with sufficient quantity first before combining quantities of separate line items. ``` { "strategy": "items_bundle", "children": [ { "strategy": "and", "children": [ { "strategy": "item_category", "operator": "in", "args": [ "667d9fae-d8c7-4941-b556-70cb4b8612f1" ] }, { "strategy": "item_quantity", "operator": "gte", "args": [ 2 ] } ] } ] } ``` - When using `item_quantity` to target specific items or categories, the required quantity can be fulfilled by a combination of eligible items. - For example, if the rule is `item_quantity` with operator `eq` 3 for products in the "Office Supplies" category, the discount will apply when the cart includes any of the following combinations: - 2 packs of printer paper + 1 box of pens - 1 stapler + 2 notepad - 1 box of pens + 1 notepad + 1 pack of printer paper - 3 identical items, such as 3 boxes of pens - **Please Note**: the system considers line items sequentially based on their quantities, using the order of addition to the cart as a fallback tie-breaker. If the first eligible item has sufficient quantity to fulfill the bundle criteria, it will consume the required quantity and complete the evaluation for that criteria. The system does not re-evaluate these processed items to share any remaining quantities with other items. This behaviour may result in differing total discount amounts for two shopping carts with the same items added in a different order if those items have the same quantity values. Available discount types: - `fixed_price` – Sets a fixed total price for the group (e.g., If the fixed price is set at $100, then the group's subtotal is exactly $100) - `percent` – Applies a percentage-based discount to the group. - `fixed` – Deducts a fixed amount from the group's total price. Security Scheme Type: http HTTP Authorization Scheme: bearer Contact Elastic Path: URL: [https://elasticpath.com](https://elasticpath.com) License MIT --- ## Update a Rule Promotion import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Updates an existing Rule Promotion specified by its promotion ID. This includes both **semantic and syntactic validation** to ensure correctness. For example, the start date must be earlier than the end date. Editable fields include: - `name` - `description` - `enabled` - `start` - `end` - `automatic` - `stackable` - `override_stacking` - `rule_set` :::note When updating the `automatic` field from `false` to `true`, the store must not exceed the maximum limit of **50 active and future automatic rule promotions**. ::: Request --- ## Administrator Latest Releases Catalog API Use the Administrator Latest Releases Catalog View API to retrieve product, hierarchy and node information. :::danger The Administrator Latest Releases Catalog View API is for Administrator use only. Do not use these endpoints on your customer-facing frontends. ::: Publishing a catalog creates a release of that catalog that you can use in an organization or in a specific store or other shopper experience. You can retrieve the hierarchies, nodes, and the `live` products associated with a catalog release. You can see which parent nodes a product is associated with. This is useful if want to improve how your shoppers search your store, for example. Currently, published catalogs are limited to the current release and two releases prior to the current release. ```mdx-code-block import DocCardList from '@theme/DocCardList'; import {useCurrentSidebarCategory} from '@docusaurus/theme-common'; ``` --- ## Catalogs Introduction import ApiLogo from "@theme/ApiLogo"; import Heading from "@theme/Heading"; import SchemaTabs from "@theme/SchemaTabs"; import TabItem from "@theme/TabItem"; import Export from "@theme/ApiExplorer/Export"; Use the catalog-view Service API to create your catalogs. You also have the flexibility to create catalogs for different scenarios by combining hierarchies of products with a price book. Scenarios might include: - Multiple geographical regions. Display different catalogs in different regions with suitable pricing or combine product hierarchies from two different regions to display in a third region. - Multiple channels. Display different catalogs based on how a shopper accesses your store, such as through a mobile app or a web storefront. - Direct to business versus direct to customers. Offer different products and prices for business customers versus retail customers. - Preferred customers. Offer special pricing to preferred customers while displaying a standard price catalog to all other shoppers. - Reward programs. Enable reward programs where catalog prices drop after a certain spending level is reached. - Product sales. Offer sale items for a limited time. Scenarios are created by defining the context within which a catalog is displays. Contexts can be a customer ID, a channel, or any other user-defined tag that can be passed to the APIs from the front-end shopper experiences. Security Scheme Type: http HTTP Authorization Scheme: bearer --- ## Catalogs A catalog contains the products available for sale either in your organization or store. A catalog also contains information about how to organize those products for navigation menus and search facets in a shopper experience. Before you create a catalog you must define the following resources: - Hierarchies: hierarchies and nodes to categorize the products. See [**Hierarchies**](/docs/api/pxm/products/hierarchies). - Products: product information, associated assets, and links to hierarchy nodes. See [**Products**](/docs/api/pxm/products/products). - Price Books: prices for the products associated with the hierarchies. See [**Price Books**](/docs/api/pxm/pricebooks). A catalog is a combination of hierarchies and a price book. ### Products Commerce automatically assigns types to the products you create. Product types can be used in catalogs. For example, in your catalog, you can filter on `parent` so that only your parent products are displayed in your storefront. You can use product tags to store or assign a key word against a product or service that you sell in your store. The product tag can then be used to describe or label that product. Product tags represent similarities between products who do not share the same attributes. Using product tags means that you can group your products together, for example, by brand, category, subcategory, colors, types, industries, and so on. Product tags can be used in catalogs. For example, you can categorize your products based on color. Your shoppers can then search your products by color, enabling shoppers to quickly find what they are looking for, increasing the likelihood of a purchase, and boosting conversion rates. ### Hierarchies The hierarchies determine which products appear in the catalog, that is, only the products that are associated with the selected hierarchies are included in the catalog. You can also specify the order you want your hierarchies to display in a published catalog. You can order your hierarchies on a catalog-by-catalog basis. ![Hierarchy_sorting](/assets/hierarchy_sorting.png) For more information, see [**create a Catalog**](/docs/api/pxm/catalog/create-catalog). #### Understanding How Products And Nodes Are Associated You can use `breadcrumb` metadata to understand how products and nodes are associated. it explains how products are associated with parent nodes and the relationship among the array of nodes. This is useful if you want to improve how your shoppers search within your store. The `breadcrumb` information that you get in an endpoint response depends on whether the endpoint is retrieving product or node details. | Object | Product/Node | Description | | --- | --- | --- | | `breadcrumb` | Node | A list of nodes that a product is associated with. Up to 10 levels of nodes are displayed, depending on the number of levels of nodes you have. | | `bread_crumbs` | Product | The relationship among the array of nodes a product is associated with, demonstrating the linking of the children nodes with the parent nodes. Up to 10 levels of nodes are displayed, depending on the number of levels of nodes you have. | | `bread_crumb_nodes` | Product | An array of parent node IDs that a product is associated with. The `bread_crumb_node` metadata lists up to 10 levels of parent nodes, depending on the number of levels of parent nodes you have. | #### Understanding `bread_crumbs` Metadata The following diagram illustrates a parent and child nodes. ![Breadcrumbs](/assets/breadcrumbs.PNG) 1. The product is in **Node 2**. The ID for **Node 2** is shown first in the first set of breadcrumbs. 1. **Node 2** is part of **Hierarchy 1**. The ID for **Hierarchy 1** is shown second. 1. **Node 1** is the parent node of **Node 2**. The ID for **Node 1** is shown last. 1. The product is also in **Node 3**. The ID for **Node 3** is shown first in the second set of breadcrumbs. 1. **Node 3** is in the root of **Hierarchy 1**. The ID for **Hierarchy 1** is shown last. In the `bread_crumb_nodes` metadata, you can see a list of parent nodes a product is associated with. If you subsequently add a product to a new node, then the `bread_crumb_nodes` metadata appends the new node to the top of the list. Using the example above, if we add the product to **Node 1**: 1. The `bread_crumb_nodes` metadata is generated to show the new node appended to the top of the list. 1. The `bread_crumbs` metadata is updated with the new node. #### Understanding Breadcrumb Metadata for Child Products When a catalog is published, the breadcrumb information for a child product includes the metadata mentioned for the parent product, in addition to the information specific to the child product. For example, **Product A** is the parent product, associated with **Node 1** and **Node 2**. The metadata for child **Product B** includes **Node 1** and **Node 2**, in addition to its own metadata information. ### Nodes The nodes determine which products appear under this in the catalog, that is, only the products that are associated with the selected node are shown under this node. ### Price books A price book contains the prices for each of the products in the catalog. You can create multiple price books for different scenarios, such as seasonal sales, business versus retail customer pricing, and reward programs. When creating a catalog, you can specify up to five price books. You must set a priority for your price books. Product prices are displayed in the catalog according to the priority of the price books. See [Create a catalog](/docs/api/pxm/catalog/create-catalog). ```mdx-code-block import DocCardList from '@theme/DocCardList'; import {useCurrentSidebarCategory} from '@docusaurus/theme-common'; ``` --- ## Configure a Shopper Bundle import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Once you have configured your product bundles, you can display them in your storefront in your published catalog. Depending on how you have configured the minimum and maximum values for the product options in your components, you can allow your shoppers to choose which products they want to select. For example, you can enable a shopper to select 1 or more product options from a list of 10, giving your shoppers greater flexibility when selecting products in your store front. - Products must be in a `live` status. - If you have not specified any minimum or maximum values for the product options in your components, your shoppers can select any combination of product options. If you have configured minimum and maximum values using [Create a Bundle](/docs/api/pxm/products/create-product), this becomes part of the `bundle_configuration`. You can check how your bundle is configured using [Get a product in a catalog release](/docs/api/pxm/catalog/get-product) in `bundle_configuration` under `meta`. The `bundle_configuration` forms the body of the request. The response updates the `bundle_configuration` with the product options the shopper selects. The `meta` data is updated with the `meta` data of the selected product options. In your storefront, you could display this as a summary of the product options a shopper has selected. ### Including Resources Using the `include` parameter, you can retrieve top-level resources, such as, files or main image, bundle component products and product attributes, such as SKU or slug. | Parameter | Required | Description | | :---------------------|:---------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | `component_products` | Optional | The component product data and key attribute data, such as SKU or slug, to return for component products in a product bundle. | | `main_image` | Optional | The main images associated with a product. | | `files` | Optional | Any files associated with a product. | See [**Including Resources**](/guides/Getting-Started/includes). Request --- ## Creates a new catalog import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Before you create a catalog, you must define the following resources: - Hierarchies - hierarchies and nodes to categorize the products. - Products - product information, associated assets, and links to hierarchy nodes. - Price Books - prices for the products associated with the hierarchies. You can create multiple price books for different scenarios, such as seasonal sales, business versus retail customer pricing, and reward programs. When creating a catalog, you can specify up to five price books. You must configure a priority for your price books. Product prices are displayed in the catalog according to the priority of the price books. Priority is a number and the price book with the highest number has the highest priority. Request --- ## Creates a new catalog rule import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; If you have multiple catalogs, create catalog rule resources. With catalog rules, you can display different catalogs to different shoppers. For example, you can display a preferred pricing catalog to a few special customers. Or you can display one catalog to shoppers using your website and a different catalog to shoppers using your mobile app. Finally, you can define custom criteria by creating tags. :::note - If you have one catalog for all customers and channels, you can omit creating this resource. - Due to the way catalogs are cached in Commerce, using catalog rules to display catalogs sometimes causes a 5-minute time delay before the catalogs are displayed. - You cannot create catalog rules for organization catalogs. ::: For ideas about the kinds of business scenarios you can achieve with catalog rules, see [Catalog Rules](/docs/api/pxm/catalog/rules). To understand how catalogs are matched to shoppers by using rules, see [Resolving Catalog Rules](/docs/api/pxm/catalog/rules#resolving-catalog-rules). Request --- ## Deletes a catalog import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Deletes an unpublished catalog. Use [**Delete a Release**](/docs/api/pxm/catalog/delete-release-by-id) and [**Delete All Releases**](/docs/api/pxm/catalog/delete-releases) to delete releases of a catalog. If the catalog is associated with any catalog rules, you must first update the catalog rules to remove the catalog. Request --- ## Deletes a release import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Deletes the specified published catalog release. Request --- ## Deletes all releases import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Deletes all releases of the specified published catalog. Request --- ## Deletes a catalog rule import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Deletes a catalog rule Request --- ## Get all Hierarchies import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Returns the hierarchies from a published catalog. :::note Currently, published catalogs are limited to the current release and two releases prior to the current release. ::: ### Filtering This endpoint supports filtering. For general syntax, see [Filtering](/guides/Getting-Started/filtering). | Operator | Description | Supported Attributes | Example | |:--- |:--- |:--- |:--- | | `Eq` | Checks if the values of two operands are equal. If they are, the condition is true. | `name`, `slug`| `filter=eq(name,some-name)` | | `In` | Checks if the values are included in the specified string. If they are, the condition is true. | `id` | `filter=in(id,some-id)` | ### Building breadcrumbs in a storefront In a catalog, you can use the nodes directly attached to a product to build breadcrumbs in your storefront. This eliminates the need for additional queries to fetch hierarchy or parent node details. Each node contains all the necessary information in `breadcrumbs` metadata, such as its own details and the details of its parent hierarchy/node(s), to construct the complete breadcrumb path without requiring additional queries. An example is shown below: `filter=in(id,c83bfe55-0d87-4302-a86d-ab19e7e323f1,6003d7ef-84f3-49bb-a8bd-4cbfa203dcbb)` - Specify the node IDs directly attached to the product in the filter expression. - You can include as many node IDs as required. - It does not matter what order you specify the node IDs. The nodes are returned in the order they were last updated. Request --- ## Get all Nodes import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Returns the child nodes from a published catalog. :::note Currently, published catalogs are limited to the current release and two releases prior to the current release. ::: You can see the parent nodes a node is associated with in the `breadcrumbs` metadata for each node. This is useful if you want to improve how your shoppers search your store, for example. See [Product and Node Associations in Breadcrumb Metadata](/guides/How-To/Catalogs/breadcrumbs). In a catalog, you can use a filter to return a list of nodes in a hierarchy structure that a product belongs to. You can use this to build breadcrumbs in your storefront. See [Building breadcrumbs in a storefront](#building-breadcrumbs-in-a-storefront). The response lists the products associated with the nodes. If products are [curated](/guides/How-To/Products/curating-products), they are displayed in `curated_products`. Product curation allows you to promote specific products within each of your hierarchies, enabling you to create unique product collections in your storefront. - If you don't provide any `curated_products`, products are listed by their `updated_at` time in descending order, with the most recently updated product first. - If you configure `curated_products` for only a few products, the curated products are displayed first and the other products are displayed in the order of `updated_at` time. - You can only curate 20 products or less. You cannot have more than 20 curated products. - If a curated product is removed from a node, the product is also removed from the `curated_products` list. - A product that is curated has the `"curated_product": true` attribute displayed. ### Filtering This endpoint supports filtering. For general syntax, see [Filtering](/guides/Getting-Started/filtering). The following operators and attributes are available. | Operator | Description | Attributes | Example | | --- | --- | --- | --- | | `Eq` | Checks if the values of two operands are equal. If they are, the condition is true. | `name`, `slug` | `filter=eq(name,some-name)` | | `in` | Checks if the values are included in the specified string. If they are, the condition is true. | `Id` | `filter=in(id,9214719b-17fe-4ea7-896c-d61e60fc0d05,e104d541-2c52-47fa-8a9a-c4382480d97c,65daaf68-ff2e-4632-8944-370de835967d)` | ### Building breadcrumbs in a storefront In a catalog, you can use the nodes directly attached to a product to build breadcrumbs in your storefront. This eliminates the need for additional queries to fetch hierarchy or parent node details. Each node contains all the necessary information in `breadcrumbs` metadata, such as its own details and the details of its parent hierarchy/node(s), to construct the complete breadcrumb path without requiring additional queries. An example is shown below: `filter=in(id,c83bfe55-0d87-4302-a86d-ab19e7e323f1,6003d7ef-84f3-49bb-a8bd-4cbfa203dcbb)` - Specify the node IDs directly attached to the product in the filter expression. - You can include as many node IDs as required. - It does not matter what order you specify the node IDs. The nodes are returned in the order they were last updated. Request --- ## Get all Products import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Returns the products from a published catalog. Only the products in a `live` status are retrieved. Currently, published catalogs are limited to the current release and two releases prior to the current release. You can see the parent nodes a product is associated with in the `bread_crumbs` and `bread_crumb_nodes` metadata for each product. This is useful if you want to improve how your shoppers search your store, for example. See [Product and Node Associations in Breadcrumb Metadata](/guides/How-To/Catalogs/breadcrumbs). The `variations` object lists the variation IDs and variation option IDs and their corresponding product IDs that are generated when the variation and variation options are built with a product. The `variations` object can then be added to your catalogs. By default, variations and variation options are sorted randomly. You can use the `sort_order` attribute to sort the order of your variation and variation options in `variations`. Once a parent product is published in a catalog, the [Get a List of products in a catalog release](/docs/api/pxm/catalog/get-all-products) response displays the sorted variations and variation options. Variations and variation options are displayed in descending order according to their `sort_order` values. ### Including Resources Using the `include` parameter, you can retrieve top-level resources, such as, files or main image, bundle component products and product attributes, such as SKU or slug. | Parameter | Required | Description | | :---------------------|:---------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | `component_products` | Optional | The component product data and key attribute data, such as SKU or slug, to return for component products in a product bundle. | | `main_image` | Optional | The main images associated with a product. | | `files` | Optional | Any files associated with a product. See [**Including Resources**](/guides/Getting-Started/includes). ### Filtering This endpoint supports filtering. For general filtering syntax, see [Filtering](/guides/Getting-Started/filtering). The following operators and attributes are available when filtering on this endpoint. | Operator | Description | Supported Attributes | Example | |:---|:------------------------------------------------------------------------------------------------|:---------------------------------------------------------|:--- | | `Eq` | Checks if the values of two operands are equal. If they are, the condition is true. For `product_types`, you can only specify one product type. For example, `filter=eq(product_types,child)`. | `name`, `sku`, `slug`, `manufacturer_part_num`, `upc_ean`, `product_types`, `tags` | `filter=eq(name,some-name)` | | `In` | Checks if the values are included in the specified string. If they are, the condition is true. For `product_types`, you can specify more than one product type. For example, `filter=in(product_types,child,bundle)`. | `id`, `name`, `sku`, `slug`, `manufacturer_part_num`, `upc_ean`, `product_types`, `tags` | `filter=in(id,some-id)` | ### Building breadcrumbs in a storefront In a catalog, you can use the nodes directly attached to a product to build breadcrumbs in your storefront. This eliminates the need for additional queries to fetch hierarchy or parent node details. Each node contains all the necessary information in `breadcrumbs` metadata, such as its own details and the details of its parent hierarchy/node(s), to construct the complete breadcrumb path without requiring additional queries. An example is shown below: `filter=in(id,c83bfe55-0d87-4302-a86d-ab19e7e323f1,6003d7ef-84f3-49bb-a8bd-4cbfa203dcbb)` - Specify the node IDs directly attached to the product in the filter expression. - You can include as many node IDs as required. - It does not matter what order you specify the node IDs. The nodes are returned in the order they were last updated. Request --- ## Get all Related Products of a Product import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Returns related products of the provided product ID from a published catalog. Request --- ## Get all Hierarchies(Catalog) import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Returns all hierarchies from a catalog. If you have multiple catalog rules defined, the rule that best matches the shoppers context is used to determine which catalog is retrieved. For information about how rules are matched, see [Resolving Catalog Rules](/docs/api/pxm/catalog/rules#resolving-catalog-rules). ### Filtering This endpoint supports filtering. For general syntax, see [Filtering](/guides/Getting-Started/filtering). | Operator | Description | Supported Attributes | Example | |:--- |:--- |:--- |:--- | | `Eq` | Checks if the values of two operands are equal. If they are, the condition is true. | `name`, `slug`| `filter=eq(name,some-name)` | | `In` | Checks if the values are included in the specified string. If they are, the condition is true. | `id` | `filter=in(id,some-id)` | ### Building breadcrumbs in a storefront In a catalog, you can use the nodes directly attached to a product to build breadcrumbs in your storefront. This eliminates the need for additional queries to fetch hierarchy or parent node details. Each node contains all the necessary information in `breadcrumbs` metadata, such as its own details and the details of its parent hierarchy/node(s), to construct the complete breadcrumb path without requiring additional queries. An example is shown below: `filter=in(id,c83bfe55-0d87-4302-a86d-ab19e7e323f1,6003d7ef-84f3-49bb-a8bd-4cbfa203dcbb)` - Specify the node IDs directly attached to the product in the filter expression. - You can include as many node IDs as required. - It does not matter what order you specify the node IDs. The nodes are returned in the order they were last updated. Request --- ## Get all Nodes(Catalog) import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Returns all nodes in the catalog. If you have multiple catalog rules defined, the rule that best matches the shoppers context is used to determine which catalog is retrieved. For information about how rules are matched, see [Resolving Catalog Rules](/docs/api/pxm/catalog/rules#resolving-catalog-rules). You can see the parent nodes a node is associated with in the `breadcrumbs` metadata for each node. This is useful if you want to improve how your shoppers search your store, for example. See [Product and Node Associations in Breadcrumb Metadata](/guides/How-To/Catalogs/breadcrumbs). In a catalog, you can use a filter to return a list of nodes in a hierarchy structure that a product belongs to. You can use this to build breadcrumbs in your storefront. For more information, see [Building breadcrumbs in a storefront](#building-breadcrumbs-in-a-storefront). The response lists the products associated with the nodes. If products are [curated](/guides/How-To/Products/curating-products), they are displayed in `curated_products`. Product curation allows you to promote specific products within each of your hierarchies, enabling you to create unique product collections in your storefront. - You can only curate 20 products or less. You cannot have more than 20 curated products. - If a curated product is removed from a node, the product is also removed from the `curated_products` list. ### Filtering This endpoint supports filtering. For general syntax, see [Filtering](/guides/Getting-Started/filtering). The following operators and attributes are available. | Operator | Description | Attributes | Example | | --- | --- | --- | --- | | `Eq` | Checks if the values of two operands are equal. If they are, the condition is true. | `name`, `slug` | `filter=eq(name,some-name)` | | `in` | Checks if the values are included in the specified string. If they are, the condition is true. | `Id` | `filter=in(id,9214719b-17fe-4ea7-896c-d61e60fc0d05,e104d541-2c52-47fa-8a9a-c4382480d97c,65daaf68-ff2e-4632-8944-370de835967d)` | ### Building breadcrumbs in a storefront In a catalog, you can use the nodes directly attached to a product to build breadcrumbs in your storefront. This eliminates the need for additional queries to fetch hierarchy or parent node details. Each node contains all the necessary information in `breadcrumbs` metadata, such as its own details and the details of its parent hierarchy/node(s), to construct the complete breadcrumb path without requiring additional queries. An example is shown below: `filter=in(id,c83bfe55-0d87-4302-a86d-ab19e7e323f1,6003d7ef-84f3-49bb-a8bd-4cbfa203dcbb)` - Specify the node IDs directly attached to the product in the filter expression. - You can include as many node IDs as required. - It does not matter what order you specify the node IDs. The nodes are returned in the order they were last updated. Request --- ## Get all Products(Catalog) import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Retrieves the list of products from the catalog. Only the products in a live status are retrieved. ### Catalog Rules If you have multiple catalog rules defined, the rule that best matches the shoppers context is used to determine which catalog is retrieved. If no catalog rules are configured, the first catalog found is returned. For information about how rules are matched, see [Resolving Catalog Rules](/docs/api/pxm/catalog/rules#resolving-catalog-rules). ### Product and Node Associations You can see the parent nodes a product is associated within the `bread_crumbs` and `bread_crumb_nodes` metadata for each product. For example, this is useful if you want to improve how your shoppers search your store. See [Product and Node Associations in Breadcrumb Metadata](/guides/How-To/Catalogs/breadcrumbs). ### Including Resources Using the `include` parameter, you can retrieve top-level resources, such as, files or main image, bundle component products and product attributes, such as SKU or slug. | Parameter | Required | Description | | :---------------------|:---------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | `component_products` | Optional | The component product data and key attribute data, such as SKU or slug, to return for component products in a product bundle. | | `main_image` | Optional | The main images associated with a product. | | `files` | Optional | Any files associated with a product. | See [**Including Resources**](/guides/Getting-Started/includes). ### Filtering This endpoint supports filtering. For general filtering syntax, see [Filtering](/guides/Getting-Started/filtering). The following operators and attributes are available when filtering on this endpoint. | Operator | Description | Supported Attributes | Example | |:---|:------------------------------------------------------------------------------------------------|:---------------------------------------------------------|:--- | | `Eq` | Checks if the values of two operands are equal. If they are, the condition is true. For `product_types` and `tags`, you can only specify one. For example, `filter=eq(product_types,child)`. | `name`, `sku`, `slug`, `manufacturer_part_num`, `upc_ean`, `product_types`, `tags` | `filter=eq(name,some-name)` | | `In` | Checks if the values are included in the specified string. If they are, the condition is true. For `product_types` and `tags`, you can specify more than one. For example, `filter=in(product_types,child,bundle)`. | `id`, `name`, `sku`, `slug`, `manufacturer_part_num`, `upc_ean`, `product_types`, `tags` | `filter=in(id,some-id)` | ### Building breadcrumbs in a storefront In a catalog, you can use the nodes directly attached to a product to build breadcrumbs in your storefront. This eliminates the need for additional queries to fetch hierarchy or parent node details. Each node contains all the necessary information in `breadcrumbs` metadata, such as its own details and the details of its parent hierarchy/node(s), to construct the complete breadcrumb path without requiring additional queries. An example is shown below: `filter=in(id,c83bfe55-0d87-4302-a86d-ab19e7e323f1,6003d7ef-84f3-49bb-a8bd-4cbfa203dcbb)` - Specify the node IDs directly attached to the product in the filter expression. - You can include as many node IDs as required. - It does not matter what order you specify the node IDs. The nodes are returned in the order they were last updated. Request --- ## Get all Related Products of a Product(Catalog) import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Returns related products of the provided product ID from a catalog. Request --- ## Get a Node's Children import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Returns the child nodes for a node in the catalog. If you have multiple catalog rules defined, the rule that best matches the shoppers context is used to determine which catalog is retrieved. For information about how rules are matched, see [Resolving Catalog Rules](/docs/api/pxm/catalog/rules#resolving-catalog-rules). You can see which parent nodes a node is associated with in the `breadcrumbs` metadata for each node. This is useful if you want to improve how your shoppers search your store, for example. See [Product and Node Associations in Breadcrumb Metadata](/guides/How-To/Catalogs/breadcrumbs). The response lists the products associated with the nodes. If products are [curated](/guides/How-To/Products/curating-products), they are displayed in `curated_products`. Product curation allows you to promote specific products within each of your hierarchies, enabling you to create unique product collections in your storefront. - If you don't provide any curated_products, products are listed by their updated_at time in descending order, with the most recently updated product first. - If you configure curated_products for only a few products, the curated products are displayed first and the other products are displayed in the order of updated_at time. - You can only curate 20 products or less. You cannot have more than 20 curated products. - A product that is curated has the "curated_product": true attribute displayed. - If a curated product is removed from a node, the product is also removed from the curated_products list. ### Filtering This endpoint supports filtering. For general syntax, see [Filtering](/guides/Getting-Started/filtering). The following operators and attributes are available. | Operator | Description | Attributes | Example | | --- | --- | --- | --- | | `Eq` | Checks if the values of two operands are equal. If they are, the condition is true. | `name`, `slug` | `filter=eq(name,some-name)` | | `in` | Checks if the values are included in the specified string. If they are, the condition is true. | `Id` | `filter=in(id,9214719b-17fe-4ea7-896c-d61e60fc0d05,e104d541-2c52-47fa-8a9a-c4382480d97c,65daaf68-ff2e-4632-8944-370de835967d)` | ### Building breadcrumbs in a storefront In a catalog, you can use the nodes directly attached to a product to build breadcrumbs in your storefront. This eliminates the need for additional queries to fetch hierarchy or parent node details. Each node contains all the necessary information in `breadcrumbs` metadata, such as its own details and the details of its parent hierarchy/node(s), to construct the complete breadcrumb path without requiring additional queries. An example is shown below: `filter=in(id,c83bfe55-0d87-4302-a86d-ab19e7e323f1,6003d7ef-84f3-49bb-a8bd-4cbfa203dcbb)` - Specify the node IDs directly attached to the product in the filter expression. - You can include as many node IDs as required. - It does not matter what order you specify the node IDs. The nodes are returned in the order they were last updated. Request --- ## Get a Parent Product's Child Products import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; For a specified product and catalog release, retrieves a list of child products from a parent product. Any product other than a base product results in a `422 Unprocessable Entity` response. Only the products in a `live` status are retrieved. If you have multiple catalog rules defined, the rule that best matches the shopperʼs context is used to determine which catalog is retrieved. If no catalog rules are configured, the first catalog found is returned. For information about how rules are matched, see [Resolving Catalog Rules](/docs/api/pxm/catalog/rules#resolving-catalog-rules). You can see the parent nodes a product is associated within the `breadcrumbs` metadata for each product. For example, this is useful if you want to improve how your shoppers search your store. See [Product and Node Associations in Breadcrumb Metadata](/guides/How-To/Catalogs/breadcrumbs). ### Filtering This endpoint supports filtering. For general filtering syntax, see [Filtering](/guides/Getting-Started/filtering). The following operators and attributes are available when filtering on this endpoint. | Operator | Description | Supported Attributes | Example | |:---|:------------------------------------------------------------------------------------------------|:---------------------------------------------------------|:--- | | `Eq` | Checks if the values of two operands are equal. If they are, the condition is true. For `product_types` and `tags`, you can only specify one. For example, `filter=eq(product_types,child)`. | `name`, `sku`, `slug`, `manufacturer_part_num`, `upc_ean`, `product_types`, `tags` | `filter=eq(name,some-name)` | | `In` | Checks if the values are included in the specified string. If they are, the condition is true. For `product_types` and `tags`, you can specify more than one. For example, `filter=in(product_types,child,bundle)`. | `id`, `name`, `sku`, `slug`, `manufacturer_part_num`, `upc_ean`, `product_types`, `tags` | `filter=in(id,some-id)` | ### Building breadcrumbs in a storefront In a catalog, you can use the nodes directly attached to a product to build breadcrumbs in your storefront. This eliminates the need for additional queries to fetch hierarchy or parent node details. Each node contains all the necessary information in `breadcrumbs` metadata, such as its own details and the details of its parent hierarchy/node(s), to construct the complete breadcrumb path without requiring additional queries. An example is shown below: `filter=in(id,c83bfe55-0d87-4302-a86d-ab19e7e323f1,6003d7ef-84f3-49bb-a8bd-4cbfa203dcbb)` - Specify the node IDs directly attached to the product in the filter expression. - You can include as many node IDs as required. - It does not matter what order you specify the node IDs. The nodes are returned in the order they were last updated. ### Including Resources Using the `include` parameter, you can retrieve top-level resources, such as, files or main image, bundle component products and product attributes, such as SKU or slug. | Parameter | Required | Description | | :---------------------|:---------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | `component_products` | Optional | The component product data and key attribute data, such as SKU or slug, to return for component products in a product bundle. | | `main_image` | Optional | The main images associated with a product. | | `files` | Optional | Any files associated with a product. | See [**Including Resources**](/guides/Getting-Started/includes). Request --- ## Get a Bundle's Component Products import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; With Product Experience Manager, you can [create](/docs/api/pxm/products/create-product) and manage bundles. A bundle is a purchasable product, comprising of one or more products that you want to sell together. You can create multiple components within a bundle. Each component must have at least one or more options. Each option is a product and a quantity. This endpoint returns a list of component product IDs for the specified bundle. Request --- ## Get a Hierarchy's Children import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Returns the parent nodes for the specified hierarchy. ![Parent Nodes](/assets/rootnodes.PNG) If you have multiple catalog rules defined, the rule that best matches the shopperʼs context is used to determine which catalog is retrieved. For information about how rules are matched, see [Resolving Catalog Rules](/docs/api/pxm/catalog/rules#resolving-catalog-rules). In the `breadcrumbs` metadata, you can identify the parent nodes that a node is associated with. This is useful if you want to improve how your shoppers search your store, for example. See [Product and Node Associations in Breadcrumb Metadata](/guides/How-To/Catalogs/breadcrumbs). ### Filtering The following operators and attributes are available when filtering on this endpoint. | Operator | Description | Supported Attributes | Example | |:--- |:--- |:--- |:--- | | `Eq` | Checks if the values of two operands are equal. If they are, the condition is true. | `name`, `slug`| `filter=eq(name,some-name)` | | `In` | Checks if the values are included in the specified string. If they are, the condition is true. | `id` | `filter=in(id,some-id)` | For more information, see [Filtering](/guides/Getting-Started/filtering). ### Building breadcrumbs in a storefront In a catalog, you can use the nodes directly attached to a product to build breadcrumbs in your storefront. This eliminates the need for additional queries to fetch hierarchy or parent node details. Each node contains all the necessary information in `breadcrumbs` metadata, such as its own details and the details of its parent hierarchy/node(s), to construct the complete breadcrumb path without requiring additional queries. An example is shown below: `filter=in(id,c83bfe55-0d87-4302-a86d-ab19e7e323f1,6003d7ef-84f3-49bb-a8bd-4cbfa203dcbb)` - Specify the node IDs directly attached to the product in the filter expression. - You can include as many node IDs as required. - It does not matter what order you specify the node IDs. The nodes are returned in the order they were last updated. Request --- ## Get a Hierarchy's Nodes import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Returns all the nodes for the specified hierarchy. If you have multiple catalog rules defined, the rule that best matches the shoppers context is used to determine which catalog is retrieved. For information about how rules are matched, see [Resolving Catalog Rules](/docs/api/pxm/catalog/rules#resolving-catalog-rules). In the `breadcrumbs` metadata, you can identify the parent nodes that a node is associated with. This is useful if you want to improve how your shoppers search your store, for example. See [Product and Node Associations in Breadcrumb Metadata](/guides/How-To/Catalogs/breadcrumbs). ### Filtering This endpoint supports filtering. For general syntax, see [Filtering](/guides/Getting-Started/filtering). | Operator | Description | Supported Attributes | Example | |:--- |:--- |:--- |:--- | | `Eq` | Checks if the values of two operands are equal. If they are, the condition is true. | `name`, `slug`| `filter=eq(name,some-name)` | | `In` | Checks if the values are included in the specified string. If they are, the condition is true. | `id` | `filter=in(id,some-id)` | ### Building breadcrumbs in a storefront In a catalog, you can use the nodes directly attached to a product to build breadcrumbs in your storefront. This eliminates the need for additional queries to fetch hierarchy or parent node details. Each node contains all the necessary information in `breadcrumbs` metadata, such as its own details and the details of its parent hierarchy/node(s), to construct the complete breadcrumb path without requiring additional queries. An example is shown below: `filter=in(id,c83bfe55-0d87-4302-a86d-ab19e7e323f1,6003d7ef-84f3-49bb-a8bd-4cbfa203dcbb)` - Specify the node IDs directly attached to the product in the filter expression. - You can include as many node IDs as required. - It does not matter what order you specify the node IDs. The nodes are returned in the order they were last updated. Request --- ## Get a Hierarchy import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Returns a hierarchy from the catalog. If you have multiple catalog rules defined, the rule that best matches the shoppers context is used to determine which catalog to retrieve. For information about how catalog rules are matched, see [Resolving Catalog Rules](/docs/api/pxm/catalog/rules). Request --- ## Get a Node import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Returns a node from the catalog. If you have multiple catalog rules defined, the rule that best matches the shoppers context is used to determine which catalog is retrieved. For information about how rules are matched, see [Resolving Catalog Rules](/docs/api/pxm/catalog/rules#resolving-catalog-rules). You can see the parent nodes a node is associated with in the `breadcrumbs` metadata for each node. This is useful if you want to improve how your shoppers search your store, for example. See [Product and Node Associations in Breadcrumb Metadata](/guides/How-To/Catalogs/breadcrumbs). The response lists the products associated with a node. If products are [curated](/guides/How-To/Products/curating-products), they are displayed in `curated_products`. Product curation allows you to promote specific products within each of your nodes, enabling you to create unique product collections in your storefront. - If you don't provide any `curated_products`, products are listed by their `updated_at` time in descending order, with the most recently updated product first. - If you configure `curated_products` for only a few products, the curated products are displayed first and the other products are displayed in the order of `updated_at` time. - You can only curate 20 products or less. You cannot have more than 20 curated products. - A product that is curated has the `"curated_product": true` attribute displayed. - If a curated product is removed from a node, the product is also removed from the `curated_products` list. Request --- ## Get a Product import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; import ParamsDetails from "@theme/ParamsDetails"; import RequestSchema from "@theme/RequestSchema"; import StatusCodes from "@theme/StatusCodes"; import OperationTabs from "@theme/OperationTabs"; import TabItem from "@theme/TabItem"; import Heading from "@theme/Heading"; import Translate from "@docusaurus/Translate"; Returns the specified product from the catalog. The product must be in the `live` status. If you have multiple catalog rules defined, the rule that best matches the shoppers context is used to determine which catalog is retrieved. For information about how rules are matched, see [Resolving Catalog Rules](/docs/api/pxm/catalog/rules#resolving-catalog-rules). You can see the parent nodes a product is associated with in the `bread_crumbs` and `bread_crumb_nodes` metadata for each product. This is useful if you want to improve how your shoppers search your store, for example. See [Product and Node Associations in Breadcrumb Metadata](/guides/How-To/Catalogs/breadcrumbs). Using the `include` parameter, you can retrieve top-level resources, such as, files or main image, bundle component products and product attributes, such as SKU or slug. | Parameter | Required | Description | | :---------------------|:---------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | `component_products` | Optional | The component product data and key attribute data, such as SKU or slug, to return for component products in a product bundle. | | `main_image` | Optional | The main images associated with a product. | | `files` | Optional | Any files associated with a product. | See [**Including Resources**](/guides/Getting-Started/includes). Request