Last active
November 10, 2021 19:36
-
-
Save JakobG-dev/d35d42c1158116b12f187cc878a3de53 to your computer and use it in GitHub Desktop.
Snipcart custom shipping method built with Firebase Cloud functions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"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 | |
} | |
] | |
] | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* 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