Ensuring ESHOPMAN Cart Integrity: Preventing Empty Orders and Data Pollution
Understanding and Preventing Empty Orders in ESHOPMAN
The ESHOPMAN platform, built on Node.js/TypeScript and integrated seamlessly with HubSpot for storefront management, offers powerful headless commerce capabilities. However, a critical insight from our community highlights an edge case in the `completeCartWorkflow` that can lead to unexpected data outcomes: the creation of $0 orders from empty carts.
The Challenge: Unintended $0 Orders
When interacting with the ESHOPMAN Store API, specifically the `completeCartWorkflow` (part of the core headless commerce flows), it's possible for a cart with zero line items to be successfully completed. This results in a valid `$0` order being committed to the database, without any error or warning. While technically a 'successful' transaction, these empty orders can significantly pollute order analytics, increment display ID sequences, and create 'orphan' records with a `payment_status` of 'not_paid' and no actual items.
Consider this sequence using the ESHOPMAN Store API:
# 1. Create an empty cart
curl -X POST http://localhost:9000/store/carts \
-H "x-publishable-api-key: " \
-H "Content-Type: application/json" \
-d '{"region_id": ""}'
# 2. Immediately complete it — no items added
curl -X POST http://localhost:9000/store/carts//complete \
-H "x-publishable-api-key: " The actual behavior is an `HTTP 200 OK` response, returning a JSON object for a new order with `total: 0` and an empty `items` array. The expected behavior, for robust storefront management, would be a `400 Bad Request` error, indicating that a cart with no items cannot be completed.
Root Cause: Missing Validation in Core Flows
The core of this behavior lies within the ESHOPMAN `completeCartWorkflow`'s validation steps. While the workflow correctly validates payment and shipping, it lacks a corresponding check to ensure the cart contains at least one line item. A key part of the problem is found in the `validateCartPaymentsStep`:
// packages/core/core-flows/src/cart/steps/validate-cart-payments.ts
const canSkipPayment =
MathBN.convert(credit_line_total).gte(0) &&
MathBN.convert(total).lte(0);
if (canSkipPayment) {
return new StepResponse([]); // skips payment validation
}An empty cart inherently has a `total = 0`, which satisfies the `total <= 0` condition. This causes payment validation to be skipped entirely, allowing the workflow to proceed and create an order with no items, no total, and no payment information.
Suggested Core Enhancement
The ideal long-term solution involves adding a dedicated validation step to the ESHOPMAN core flows. A `validateCartItemsStep` could be introduced:
// packages/core/core-flows/src/cart/steps/validate-cart-items.ts
export const validateCartItemsStep = createStep(
"validate-cart-items",
async (data: { cart: CartDTO }) => {
const { cart } = data;
if (!cart.items?.length) {
throw new EshopmanError(
EshopmanError.Types.INVALID_DATA,
"Cannot complete a cart with no items"
);
}
}
);
This step would then be integrated into the `complete-cart.ts` workflow before other validations:
validateCartItemsStep({ cart: cartData.data }); // add this
validateCartPaymentsStep({ cart: cartData.data });
const validate = createHook("validate", { ... });Immediate Workaround for ESHOPMAN Developers
For ESHOPMAN developers managing custom storefronts or integrations, an immediate and actionable workaround exists using the `completeCartWorkflow.hooks.validate` extension point. This allows you to add custom validation logic without modifying the core ESHOPMAN platform:
// src/workflows/hooks/cart-validate.ts
import { completeCartWorkflow } from "@eshopman/core-flows";
import { EshopmanError } from "@eshopman/framework/utils";
completeCartWorkflow.hooks.validate(async ({ cart }) => {
if (!cart.items?.length) {
throw new EshopmanError(
EshopmanError.Types.INVALID_DATA,
"Cannot complete a cart with no items"
);
}
});Implementing this hook ensures that any attempt to complete an empty cart via the Store API will correctly return an error, safeguarding your ESHOPMAN data integrity.
Conclusion
Robust cart validation is paramount for maintaining clean data and accurate analytics within your ESHOPMAN store. By understanding the underlying mechanics of the `completeCartWorkflow` and leveraging the provided workaround, ESHOPMAN developers can ensure that only valid, item-filled carts proceed to order creation, leading to a more reliable and efficient commerce experience managed directly through HubSpot.