I’m currently working on creating a functionality to customize Shipping Zones using a self-made API server based on Node.js, utilizing the CarrierService API. Although similar to the functionality of existing apps like “Custom zip code base shipping,” this feature differs in that it accepts address input for countries that do not use zip codes. The goal is to charge $20 if the address belongs to the desired region and $29 if it falls outside that region.
To determine if an address belongs to the desired region, I have incorporated Google Maps API for development.
During development and testing, I encountered the following issue and decided to seek assistance:
- Prerequisite: Using the following webhooks, when a user enters an address or clicks a button, the self-made API server receives address information as a req parameter via the PUT function of the CarrierService API.
The webhooks I’m monitoring are Checkout Creation, Checkout Update, Cart Creation, and Cart Update. However, I’ve encountered the following issue with these webhooks:
- Checkout Creation and Checkout Update webhooks trigger when the user moves to the “Shipping” section. During debugging, I discovered that these webhooks first call the callback URL containing the previously registered shipping payment information.
After receiving the address, I use the Google Maps API to determine if the address falls within the desired region. If it does, I make a PUT request to the CarrierService API with the following JSON as the callback:
// Callback URL for “total_price”: “20” when the address is within the range router.get(‘/in’, (req: Request, res: Response) => { const jsonData = { “rates”: [ { “service_name”: “cityRange”, “service_code”: “ON”, “total_price”: “20”, “description”: “This is the fixed fee in a range”, “currency”: “VND”, “min_delivery_date”: “2013-04-12 14:48:45 -0400”, “max_delivery_date”: “2024-04-12 14:48:45 -0400” } ] }; res.send(jsonData); });
// Callback URL for “total_price”: “29” when the address is outside the range router.get(‘/out’, (req: Request, res: Response) => { const jsonData = { “rates”: [ { “service_name”: “cityOutOfRange”, “service_code”: “ON”, “total_price”: “29”, “description”: “This is the fixed fee in a range”, “currency”: “VND”, “min_delivery_date”: “2013-04-12 14:48:45 -0400”, “max_delivery_date”: “2024-04-12 14:48:45 -0400” } ] }; res.send(jsonData); });
Based on these two types of callback URLs, I make updates using the PUT command of the CarrierService API, depending on the scenario. However, the most significant issue I’m facing is the synchronization of policies. That is, when CarrierService API updates through PUT, sometimes the previous policy is still applied.
Additionally, there is an issue with the application of policies when multiple concurrent users access the system.
I would greatly appreciate any guidance on how to resolve this issue.
Here is the TypeScript code snippet related to the issue:
const accessToken = shopifyAccessToken;
const headers = {
‘X-Shopify-Access-Token’: accessToken,
‘Content-Type’: ‘application/json’,
};
const requestData = {
carrier_service: {
id: 65040482548,
name: ‘cityOutOfRange’,
active: ‘On’,
callback_url: ‘https://9a85-218-153-85-41.ngrok-free.app/api/out’,
service_discovery: true,
},
};
axios.put(apiUrl, requestData, { headers })
.then(() => {
// @TS-ignore
console.log(requestData.carrier_service.callback_url);
console.log(‘CarrierService update successful’);
})
.catch((error) => {
console.error(‘CarrierService update failed’);
console.error(error.response.data);
});

