Skip to content

Instantly share code, notes, and snippets.

@JakobG-dev
Last active November 10, 2021 19:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JakobG-dev/d35d42c1158116b12f187cc878a3de53 to your computer and use it in GitHub Desktop.
Save JakobG-dev/d35d42c1158116b12f187cc878a3de53 to your computer and use it in GitHub Desktop.
Snipcart custom shipping method built with Firebase Cloud functions
{
"rates": [
[
{
"label": {
"en": "Free Shipping",
"de": "Kostenloser Versand"
},
"minTotoal": 29.0,
"shippingCost": 0.0,
"countries": ["AT"]
},
{
"label": {
"en": "Standard Shipping",
"de": "Standard Versand"
},
"shippingCost": 3.0,
"countries": ["AT"]
},
{
"label": {
"en": "Free Shipping (EU)",
"de": "Kostenloser Versand (EU)"
},
"minTotoal": 29.0,
"shippingCost": 0.0,
"countries": ["BE","BG","HR","CY","CZ","DK","EE","FI","FR","DE","GR","HU","IE","IT","LV","LT","LU","MT","NL","PL","PT","RO","SK","SI","ES","SE","GB"]
},
{
"label": {
"en": "Standard Shipping (EU)",
"de": "Standard Versand (EU)"
},
"shippingCost": 8.0,
"countries": ["BE","BG","HR","CY","CZ","DK","EE","FI","FR","DE","GR","HU","IE","IT","LV","LT","LU","MT","NL","PL","PT","RO","SK","SI","ES","SE","GB"]
},
{
"label": {
"en": "Free Shipping (Global)",
"de": "Kostenloser Versand (Global)"
},
"minTotoal": 59.0,
"shippingCost": 0.0
},
{
"label": {
"en": "Standard Shipping (Global)",
"de": "Standard Versand (Global)"
},
"shippingCost": 15.0
}
]
]
}
/* How to use:
1. create firebase project and add cloud function from below
2. copy shipping-rates-example.json file, modify it and host it somewhere public (some web hosting)
3. in snipcart settings enable shipping webhook with following webhook url: https://[yourfirebaseurl].cloudfunctions.net/shippingcalculator?rates_url=[url of publicly hosted shipping-rates.json file]
*/
import * as functions from "firebase-functions";
import fetch from "node-fetch";
import * as shippingRatesExample from "./shipping-rates-example.json";
type ShippingRates = typeof shippingRatesExample;
interface ResponseShippingMethodes {
description: string;
cost: number;
}
const getShippingRate = (
countryCode: string,
orderAmount: number,
lang: string,
rateData: any
): undefined | ResponseShippingMethodes => {
const foundRate = rateData.find((currentRate: any): any => {
let minimum = 0;
if (currentRate.minTotoal) {
minimum = currentRate.minTotoal;
}
const passesMinimum = minimum < orderAmount;
if (!currentRate.countries && passesMinimum) {
return true;
}
if (passesMinimum) {
const hasCountry = currentRate.countries.find((country: string) => country === countryCode);
if (hasCountry) {
return true;
}
}
return false;
});
if (foundRate) {
return {
description: foundRate.label[lang],
cost: foundRate.shippingCost,
};
}
return undefined;
};
const getShippingRates = async (url: string): Promise<any> => {
const response = await fetch(url);
if (!response.ok) {
return response.statusText;
}
return await response.json();
};
exports.shippingCalculator = functions.https.onRequest(async (req: functions.Request, res: functions.Response) => {
// Grab the text parameter.
const ratesUrl = req.query.rates_url as string;
if (!ratesUrl) {
res.status(400).send("Please provide correct url paramenter");
}
const responseShippingMethodes: ResponseShippingMethodes[] = [];
if (req.body.eventName === "shippingrates.fetch") {
try {
const shippingRates: ShippingRates = await getShippingRates(ratesUrl);
if (!shippingRates) {
res.status(500).send("Error: no shipping config.");
}
shippingRates.rates.forEach((rateData) => {
const rate = getShippingRate(
req.body.content.shippingAddressCountry,
req.body.content.finalGrandTotal,
req.body.content.lang,
rateData
);
if (rate) {
responseShippingMethodes.push(rate);
}
});
} catch (e) {
res.status(500).send("Error: with shipping config request.");
}
}
console.log(JSON.stringify(responseShippingMethodes));
if (responseShippingMethodes.length > 0) {
const formattedDate = {
rates: responseShippingMethodes,
};
res.status(200).send(formattedDate);
} else {
res.status(404).send("Error: Could not find any shipping methode");
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment