Streamlining Fulfillment Tracking: Querying ESHOPMAN Fulfillments by Tracking Number
As an ESHOPMAN developer or merchant managing a headless commerce storefront deployed via HubSpot CMS, efficiently tracking and updating order fulfillments is crucial. Integrating with external shipping services like ShipEngine often requires querying your ESHOPMAN data based on tracking numbers. This community insight addresses a common challenge faced by users attempting to fetch fulfillments directly using tracking numbers and outlines a robust best practice.
The Challenge: Querying Fulfillments by Tracking Number in ESHOPMAN
A recent discussion highlighted a scenario where a user needed to fetch an ESHOPMAN fulfillment and its associated order to update metadata after receiving an Hupdate from a shipping provider. The core issue stemmed from the data structure: while tracking numbers are essential for external updates, they are typically stored within the fulfillment_label entity, not directly on the fulfillment entity itself.
The user attempted two primary approaches, both encountering errors:
Attempt 1: Using queryServiceModule.graph on fulfillment_label
The first attempt involved using ESHOPMAN's query service to target the fulfillment_label entity directly, filtering by tracking_number:
// const xyz = await queryServiceModule.graph({
// entity: 'fulfillment_label',
// fields: ['fulfillment_id'],
// filters: {
// tracking_number: `UPS_${trackingNumber}`,
// },
// });
This resulted in an error indicating that "Method "listFulfillmentLabels" does not exist on "fulfillment"". This suggests a potential misunderstanding of how the graph query service interacts with specific entities or that the specific method for listing fulfillment labels was not directly accessible or correctly invoked in this context.
Attempt 2: Using fulfillmentModule.listFulfillments with tracking_numbers
The second approach involved trying to directly query the fulfillment module, passing tracking_numbers as a filter:
const fulfillmentModule = req.scope.resolve('fulfillment');
const fulfillments2 = await fulfillmentModule.listFulfillments(
{
tracking_numbers: [trackingNumber],
},
{
select: ['id', 'order_id', 'metadata'],
take: 1,
}
);
This attempt failed with the error: "Trying to query by not existing property Fulfillment.tracking_numbers". This error clearly indicates that the tracking_numbers property is not a direct filterable attribute on the Fulfillment entity itself within the ESHOPMAN Admin API.
ESHOPMAN Best Practice: A Two-Step Query for Reliable Tracking
To reliably fetch a fulfillment using its tracking number, the recommended best practice within ESHOPMAN's Node.js/TypeScript environment, leveraging its Admin API, involves a two-step process. This approach ensures you correctly traverse the data relationships to retrieve the necessary fulfillment details for your HubSpot-managed storefront operations.
Step 1: Retrieve fulfillment_id from fulfillment_label
First, you need to query the fulfillment_label entity using the tracking number to obtain the associated fulfillment_id. This is the bridge between the tracking information and the actual fulfillment record.
// Assuming you have a service or module to query fulfillment labels
// This is a conceptual example, actual implementation might vary based on ESHOPMAN's module structure
const fulfillmentLabelService = req.scope.resolve('fulfillmentLabelService'); // Or similar
const label = await fulfillmentLabelService.retrieveByTrackingNumber(trackingNumber);
if (!label) {
// Handle case where label is not found
console.log(`Fulfillment label with tracking number ${trackingNumber} not found.`);
return;
}
const fulfillmentId = label.fulfillment_id;
Note: The specific service name (e.g., fulfillmentLabelService) might vary in your ESHOPMAN setup. You would typically resolve the appropriate module or service that can query fulfillment_label entities.
Step 2: Fetch the Fulfillment by fulfillment_id
Once you have the fulfillment_id, you can then use ESHOPMAN's fulfillmentModule to fetch the complete fulfillment record, including its order details and metadata.
const fulfillmentModule = req.scope.resolve('fulfillmentModule'); // Or similar
const fulfillment = await fulfillmentModule.retrieve(fulfillmentId, {
select: ['id', 'order_id', 'metadata'],
relations: ['order'], // To get related order details if needed
});
if (fulfillment) {
console.log('Fulfillment found:', fulfillment.id, 'for order:', fulfillment.order_id);
// Now you can update its metadata or perform other operations
} else {
console.log(`Fulfillment with ID ${fulfillmentId} not found.`);
}
By adopting this two-step query pattern, ESHOPMAN developers can effectively integrate external shipping updates and maintain accurate fulfillment records for their headless commerce operations, ensuring seamless storefront management within HubSpot.