TL;DR
- Weather can melt perishable goods or freeze liquids during transit – costing merchants refunds, replacements, and bad reviews.
- Shopify Functions cannot call external APIs, so you need a tiny server‑side service that fetches a free weather API (e.g., OpenWeatherMap) before checkout and stores the result in a cart attribute.
- Ruleproof can then read that attribute and hide or surcharge delivery options based on temperature, precipitation, or severe‑weather alerts.
1. Why you need weather‑aware shipping
- Heat‑sensitive goods (chocolate, fresh flowers, baked items) spoil above ~25 °C – merchants lose up to 15 % of orders in summer spikes.
- Cold‑chain products (wine, paints, cosmetics) burst when temperatures dip below 0 °C – a single frozen bottle can trigger a refund and a negative review.
- Severe‑weather alerts (snow, flooding) cause carrier delays; customers expect an instant heads‑up or the option to postpone delivery.
2. Architecture overview
[Weather API] → Your tiny Node/Go service (hosted on Vercel/Render) →
writes "_weather" attribute to the cart (via Shopify Cart AJAX API)
→ Customer proceeds to checkout
→ Ruleproof checkout validation Function reads cart.attributes._weather
→ Condition hides or modifies shipping methods accordingly
- The service runs outside the sandboxed Function, so network calls are allowed.
- The attribute is read synchronously by the Function – no extra latency for the shopper.
3. Step‑by‑step implementation
3.1 Get a free weather API key
- Sign up at https://openweathermap.org/api – the free tier gives 60 calls/minute, more than enough for a typical store.
- Store the API key in your app’s
.envasWEATHER_API_KEY.
3.2 Build the sync endpoint (Node example)
// src/weather-sync.js – deployed as an HTTP endpoint
import fetch from 'node-fetch';
import { json } from 'express';
export default async function handler(req, res) {
const { postcode } = req.query; // passed from front‑end cart script
if (!postcode) return res.status(400).json({error:'postcode required'});
const apiKey = process.env.WEATHER_API_KEY;
const url = `https://api.openweathermap.org/data/2.5/weather?zip=${postcode},US&units=metric&appid=${apiKey}`;
const resp = await fetch(url);
const data = await resp.json();
const temp = data.main?.temp;
const condition = data.weather?.[0]?.main; // e.g. Rain, Snow, Clear
// Store a simplified string in the cart attribute
const attr = `temp:${Math.round(temp)}|cond:${condition}`;
// Use the Storefront Cart API – you need the cart ID from the front‑end
const cartId = req.query.cartId;
await fetch(`https://${process.env.SHOP_DOMAIN}/api/2023-07/graphql.json`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Shopify-Storefront-Access-Token': process.env.STOREFRONT_TOKEN,
},
body: JSON.stringify({
query: `mutation($id: ID!, $attr: CartAttributeInput!) {
cartAttributesUpdate(cartId: $id, attributes: [$attr]) { cart { id } }
}`,
variables: { id: cartId, attr: { key: '_weather', value: attr } },
}),
});
res.json({temp, condition});
}
Deploy this as a serverless function (Vercel, Render, Fly) – no cost for low traffic.
3.3 Hook the endpoint into the checkout UI
Add a small script to your theme’s checkout.js (or use a Checkout UI Extension) that runs after the shipping address is entered:
document.querySelector('input[name="checkout[shipping_address][zip]"]')
.addEventListener('change', async e => {
const postcode = e.target.value;
const cartId = Shopify.checkout?.cartId; // provided by Shopify
await fetch(`/api/weather-sync?postcode=${postcode}&cartId=${cartId}`);
});
- The script only calls your endpoint; it never contacts the weather API directly, keeping the checkout sandbox clean.
3.4 Add a Ruleproof condition
Edit apps/ruleproof-checkout-rules/src/conditions/weatherCondition.ts (or create a new file) with something like:
export const weatherCondition = (cart) => {
const weather = cart.attributes?._weather?.value;
if (!weather) return true; // no data -> let checkout continue
const [,tempStr] = weather.match(/temp:(-?\d+)/) ?? [];
const temp = Number(tempStr);
// Example rule: block COD if temp > 30°C
if (temp > 30 && cart.paymentMethods?.includes('cash_on_delivery')) {
return false; // cause validation error
}
return true;
};
Add the new condition to the rule builder UI (the front‑end already lists conditions from the ConditionType enum – add weatherCondition there).
4. Testing the flow
- Enable the “weather sync” script on a dev store.
- Set a mock postcode that the free API returns a hot temperature (e.g.,
33101– Miami > 30 °C in summer). - Proceed to checkout with COD selected – you should see the validation error defined in the condition.
- Change the postcode to a cooler location (e.g.,
80202– Denver) – checkout proceeds.
5. Publishing the guide
- The file lives under
sites/sushinet/content/checkout-rules/– the Sushinet build pipeline will automatically generate a page at/checkout-rules/weather-dependent-delivery-rules. - The front‑matter
publishDate: 2026-09-14places it on the editorial calendar. The built‑in content‑marketing skill will pick it up and add it to the weekly LinkedIn post queue (the skill looks fortype: "guide"and a futurepublishDate).
6. Optional extensions
- Pre‑forecast: fetch a 3‑hour forecast and hide “same‑day” delivery if rain is expected.
- Severity alerts: use the OpenWeatherMap “alerts” endpoint to block any shipping if a tornado or flood warning is active for the destination ZIP.
- Dynamic surcharge: instead of hiding a method, add a small surcharge (
$5 ice‑pack fee) when temperature exceeds 30 °C – implement by returning a custom error with asuggestedShippingMethodpayload in the Function.
This guide assumes you already have Ruleproof installed and a basic checkout‑validation Function scaffolded. No proprietary libraries required – just a free weather API and a few lines of server‑side JavaScript.