Data resilience: Cart and Customer management
Robustness often means ensuring that data remains consistent and useful even when related resources change. Two key updates in 2025 improved how the platform handles the relationship between Customers and Carts.
- Cart preservation on Customer deletion: previously, deleting a Customer record often meant losing the associated Cart data. Now, Carts are preserved when a Customer is deleted. The Cart becomes unassociated, allowing businesses to maintain accurate historical data for tax reporting, inventory management, and abandoned cart analytics without needing to keep the personal data of the deleted user.
- Refined error handling for Store-specific Carts: to improve the robustness of multi-store and B2B setups, commercetools introduced better error handling for store-specific carts. If a request involves a customer who does not belong to the specific store associated with a cart, the API now provides a clear, actionable error. This prevents "silent" logic failures and makes it easier for front-end developers to guide users back to the correct store context.
Infrastructure and Security: reliable connectivity
A robust architecture requires secure and low-latency communication between commercetools and your external logic.
- Google Cloud cross-cloud connectivity: API Extensions are critical to business logic. In 2025, commercetools introduced Cross-cloud connectivity for Google Cloud. This allows extensions hosted on Google Cloud to communicate with commercetools more reliably and securely, reducing the risk of timeouts and connection failures that can occur when traffic traverses the public internet.
- Hardened customer account flows: we've improved how email verification and password reset tokens are managed to support more secure login flows: password reset tokens are now valid for 24 hours by default (down from 24 days), older tokens for email verification or password reset can be invalidated when a new token is created, older tokens for email verification or password reset are invalidated when a token is successfully redeemed, an error is returned when attempting to redeem an expired email verification or password reset token, and additionally, if a token's validity is 60 minutes or less, the token is now included in the Message.payload to help you build better asynchronous flows.
Enhanced traceability: Audit Log expansion
What’s new in the Audit Trail?
The platform now records much more specific data points when changes occur. Key highlights include:
- Detailed Customer and Business Unit changes: you can now track exactly which address type was modified (billing vs. shipping) and compare the "before and after" values when sensitive fields like email addresses or Customer Group assignments are updated.
- Security-centric logging: critical security events, such as password changes (
SetPasswordChange) and changes to address Custom Fields, are now explicitly logged. This allows security teams to pinpoint exactly when a credential or sensitive attribute was modified. - Inventory and pricing governance: for businesses managing high-scale catalogs, the Audit Log now tracks changes to inventory keys, cart quantity limits, and Standalone Prices. This ensures that any change affecting a product's "orderability" or cost is fully traceable to a specific user or API client.
- Resource relationship tracking: new
SetReferencesChangelogs for Cart Discounts and Discount Codes allow you to see exactly how promotional rules are being linked or unlinked from other platform resources, providing clarity on complex marketing logic.
These granular audit enhancements transform logging from a passive record into a strategic tool for both technical and legal teams. By linking specific configuration changes directly to business outcomes, developers can perform rapid root-cause analysis on performance shifts, while security teams gain the verifiable "paper trail" required for SOC2 and GDPR compliance. Ultimately, this transparency removes "black box" uncertainty from the order lifecycle, ensuring every change—from pricing logic to shipping methods—is fully traceable and governed.
Query performance: GraphQL optimization
Performance in a headless environment is often measured by "chattiness"—how many API calls are required to render a page.
- Request method: POST
- Endpoint: Custom-objects
- Command: Create or update CustomObject
- Body:
{
"container": "demo-data",
"key": "favorite-customers",
"value": {
"customers": [
{
"typeId": "customer",
"id": "46fbc1a6-fd3c-424c-bbf5-096ab5da0f21"
},
{
"typeId": "customer",
"id": "abcd0a05-e532-4673-9bd9-dd8e9545c24a"
},
{
"typeId": "customer",
"id": "0644172f-72ec-47f0-9784-23617f3f4a80"
}
]
}
}
Once we have our Custom Object created, let’s use the GraphQL API to see if we can expand the references within it:
// Ensure all necessary imports are included and the API client is instantiated as demonstrated in the first example.
/**
* GraphQL query to fetch favorite customers from a Custom Object
*
* This query:
* - Retrieves a Custom Object from the "demo-data" container with key "favorite-customers"
* - Expands the customer references to get full customer details
* - Returns customer id, email, first name, and last name for each favorite customer
*/
const query = `
query fetchFavoriteCustomers {
customObject(container: "demo-data", key: "favorite-customers") {
referencedResources(expand: "customers[*]") {
path
objs {
... on Customer {
id
email
firstName
lastName
}
}
}
}
}
`;
/**
* Fetches and displays favorite customers from Composable Commerce
*
* This function executes a GraphQL query to retrieve customer information
* stored in a Custom Object and logs the results to the console.
*
* @returns Promise<void> - Resolves when the query completes
* @throws Logs error to console if the GraphQL query fails
*/
async function getFavoriteCustomers(): Promise<void> {
try {
// Execute the GraphQL query via the Composable Commerce API
const result = await apiRoot.graphql().post({ body: { query } }).execute();
// Log the favorite customers data in formatted JSON
console.log("Favorite customers:");
console.log(JSON.stringify(result.body.data, null, 2));
} catch (error) {
console.error("Error executing GraphQL query:", error);
}
}
// Execute the function to fetch and display favorite customers
await getFavoriteCustomers();
Favorite customers:
{
"customObject" : {
"referencedResources" : [ {
"path" : "customers[*]",
"objs" : [ {
"id" : "46fbc1a6-fd3c-424c-bbf5-096ab5da0f21",
"email" : "seb@example.de",
"firstName" : "Sebastian",
"lastName" : "Müller"
}, {
"id" : "abcd0a05-e532-4673-9bd9-dd8e9545c24a",
"email" : "jen@example.de",
"firstName" : "Jennifer",
"lastName" : "Schmidt"
}, {
"id" : "0644172f-72ec-47f0-9784-23617f3f4a80",
"email" : "jen@example.uk",
"firstName" : "Jennifer",
"lastName" : "Jones"
} ]
} ]
}
}
There we go, thanks to this new feature, we managed to get additional information about our referenced customers and we managed to do it all using just one API request!
Summary
The 2025 updates to performance and robustness prioritize "fewer, better calls" and "safer data transitions." By optimizing GraphQL for Custom Objects, hardening infrastructure connectivity, and ensuring carts survive customer deletions, commercetools provides a more stable foundation for enterprise-grade commerce.