Select Cheapest Service
- June 10, 2017
- 126 replies
- 7 views
126 replies
- January 6, 2021
- January 21, 2021
- January 29, 2021
- March 9, 2021
- March 23, 2021
- March 23, 2021
- March 26, 2021
- March 30, 2021
- April 1, 2021
- April 7, 2021
- Author
- April 12, 2021
- April 19, 2021
- June 9, 2021
- July 6, 2021
- July 10, 2021
- Employee
- November 3, 2021
This feature is currently in development!
- November 7, 2021
Rather than just choosing the cheapest service, I would prefer to see the options with the least expensive pre-selected. That would also give the ability to choose differently if there is only a small price increase for a quicker or more reliable service.
- Employee
- November 16, 2021
The first iteration of this tool is going to focus on auto-selecting the cheapest service from a group of services you can configure yourself (as this is one of the most requested features we have). For example, if you want the cheapest standard service, cheapest 2-day service, or cheapest overnight service you can create a group that contains all available services for your connected carriers that you might want to use in that specific service class - you would then choose the group for which you want the cheapest service and ShipStation will automatically assign the service with the cheapest rate.
You'll be able to configure your service "groups" in any way that best suits your needs. Future iterations will expand the feature to other criteria... for example, you might want ShipStation to select the fastest service rather than the cheapest.
If I'm understanding your request correctly, you would want some type of message to pop up so you could compare the rates side-by-side yourself and choose, for example, a 2-day service instead of standard if it was only slightly more expensive, rather than having ShipStation auto-assign, yes? A future state of the feature that has been discussed (but would be somewhat far off) would allow you to set some sophisticated rules that say something like "if service A is less than $x or x% more than service B, choose service A"
We'd love to get some thoughts from the community on this!
- December 2, 2021
I wrote a script that does this. Feel free to use it.
I set it to run through every order that is awaiting shipment and tagged white.
Some notes;
I made it only rate UPS, Fedex, and USPS. UPS and Fedex will only rate using your main account.
It will not rate USPS Media Mail and any flat rate boxes.
Please let me know of any questions or concerns.
You can run it off my site: http://bulkbuys.net/ssrates/getratesss.php?apikey=yourapikey&apisecret=yourapisecret
of you can can upload the script onto your own site and run it there. Just call it using your apikey and apisecret.
This is the script;
<?php
$apikey = $_GET['apikey'];
$apisecret = $_GET['apisecret'];
$theapikey = ' Basic ' . base64_encode($apikey . ':' . $apisecret);
for ($i = 1; $i <= 2; $i++) {
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://ssapi.shipstation.com/orders/listbytag?orderStatus=awaiting_shipment&tagId=85175&page=". $i ."&pageSize=200",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => array(
"Host: ssapi.shipstation.com",
"Authorization:" . $theapikey,
"Accept: application/json"
),
));
$strorders = curl_exec($curl);
curl_close($curl);
$orders = json_decode($strorders,true);
foreach($orders['orders'] as $order){
$orderid = $order['orderId'];
$orderNumber = $order['orderNumber'];
$warehouseid =$order['advancedOptions']['warehouseId'];
$tozipcode = $order['shipTo']['postalCode'];
$weightvalue = $order['weight']['value'];
$weightunits = $order['weight']['units'];
$toCountry = $order['shipTo']['country'];
$s_residential = $order['shipTo']['residential'];
$carrierCode = $order['carrierCode'];
$serviceCode = $order['serviceCode'];
$packageCode = $order['packageCode'];
$confirmation = $order['confirmation'];
$dimensions = $order['dimensions'];
if($s_residential){$residential = "true";}else{$residential = "false";}
$cheapestservice = calcrates($theapikey,$orderNumber,$warehouseid,$tozipcode,$toCountry,$weightvalue,$weightunits,$residential,$packageCode,$confirmation);
echo "Cheapest service is : " ,$orderNumber," ",$cheapestservice[0]," " ,$cheapestservice[1]," ",$cheapestservice[2]," ",$cheapestservice[3];
setcheapestrates($theapikey,$orderNumber,$cheapestservice[0] ,$cheapestservice[2],$cheapestservice[3],$order['orderDate'],$order['billTo'],$order['shipTo']);
}
}
function setcheapestrates($theapikey,$orderNumber,$cheapestservice,$cheapestpackage,$cheapestcarrier,$orderDate,$billTo,$shipTo){
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://ssapi.shipstation.com/orders/createorder",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS =>"{\n \"orderNumber\": \"".$orderNumber."\",\n \"orderKey\": \"".$orderNumber."\",\n \"orderDate\": \"".$orderDate."\",\n \"orderStatus\": \"awaiting_shipment\",\n \"billTo\": ".json_encode($billTo).",\n \"shipTo\": ".json_encode($shipTo). ",\n \"carrierCode\": \"".$cheapestcarrier."\",\n \"serviceCode\": \"".$cheapestservice."\",\n \"packageCode\": \"".$cheapestpackage."\"\n}",
CURLOPT_HTTPHEADER => array(
"Host: ssapi.shipstation.com",
"Authorization:" . $theapikey,
"Content-Type: application/json"
),
));
$response = curl_exec($curl);
curl_close($curl);
echo "completed /n";
}
function calcrates($theapikey,$orderid,$warehouseid,$tozipcode,$toCountry,$weightvalue,$weightunits,$residential,$packagecode,$confirmation){
$frompostalcode = GetWarehouseLocation($warehouseid,$theapikey);
//now lets set up seperate calcs for fedex,ups, usps
$carriers = array("stamps_com","ups","fedex");
foreach ($carriers as $carrier){
$theheader = "{\n \"carrierCode\": \"".$carrier."\",\n \"serviceCode\": null,\n \"packageCode\": null,\n \"fromPostalCode\": \""
.$frompostalcode."\",\n \"toCountry\": \""
.$toCountry."\",\n \"toPostalCode\": \""
.$tozipcode."\",\n \"weight\": {\n \"value\": "
.$weightvalue.",\n \"units\": \""
.$weightunits."\"\n },\n \"dimensions\": {\n \"units\": \"inches\",\n \"length\": 7,\n \"width\": 5,\n \"height\": 6\n },\n \"confirmation\": \"".$confirmation.
"\",\n \"residential\": ".$residential . "\n }"; //\"advancedOptions\": \"{ \n \"billToMyOtherAccount\":117945\n} \n
//this works
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://ssapi.shipstation.com/shipments/getrates",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS =>$theheader,
CURLOPT_HTTPHEADER => array(
"Host: ssapi.shipstation.com",
"Authorization:" . $theapikey,
"Content-Type: application/json"
),
));
$response = curl_exec($curl);
curl_close($curl);
$resjson = json_decode($response,true);
//now lets parse teh rates, only evaluating rates with the term package or fedex or ups in the name
foreach ($resjson as $prate){
$serviceName = $prate['serviceName'];
if ((str_contains($serviceName,'USPS') AND str_contains($serviceName,'Package') AND (!str_contains($serviceName,'Media') AND (!str_contains($serviceName,'Select'))))
OR str_contains($serviceName,'UPS')
OR (str_contains($serviceName,'FedEx') AND (!str_contains($serviceName,'select')))){
$shipmentCost = $prate['shipmentCost'];
$otherCost = $prate['otherCost'];
$serviceCode = $prate['serviceCode'];
// $SellerProviderId = $prate['SellerProviderId'];
$fullrategp[$serviceCode] = $shipmentCost + $otherCost;
}
}
}
//now we run this again using current pacakgecode
foreach ($carriers as $carrier){
$theheader = "{\n \"carrierCode\": \"".$carrier."\",\n \"serviceCode\": null,\n \"packageCode\": \"".$packagecode."\",\n \"fromPostalCode\": \""
.$frompostalcode."\",\n \"toCountry\": \""
.$toCountry."\",\n \"toPostalCode\": \""
.$tozipcode."\",\n \"weight\": {\n \"value\": "
.$weightvalue.",\n \"units\": \""
.$weightunits."\"\n },\n \"dimensions\": {\n \"units\": \"inches\",\n \"length\": 7,\n \"width\": 5,\n \"height\": 6\n },\n \"confirmation\": \"".$confirmation."\",\n \"residential\": ".$residential."\n}";
//this works
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://ssapi.shipstation.com/shipments/getrates",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS =>$theheader,
CURLOPT_HTTPHEADER => array(
"Host: ssapi.shipstation.com",
"Authorization:" . $theapikey,
"Content-Type: application/json"
),
));
$response = curl_exec($curl);
curl_close($curl);
$resjson = json_decode($response,true);
//now lets parse teh rates, only evaluating rates with the term package or fedex or ups in the name
foreach ($resjson as $prate){
$serviceName = $prate['serviceName'];
if ((str_contains($serviceName,'USPS') AND str_contains($serviceName,'Package') AND (!str_contains($serviceName,'Media') AND (!str_contains($serviceName,'Select'))))
OR str_contains($serviceName,'UPS')
OR (str_contains($serviceName,'FedEx') AND (!str_contains($serviceName,'select')))){
$shipmentCost = $prate['shipmentCost'];
$otherCost = $prate['otherCost'];
$serviceCode = $prate['serviceCode'];
$fullratecp[$serviceCode] = $shipmentCost + $otherCost;
}
}
}
//now compare geeneric package to custom pacakge
$cheapestgp = min($fullrategp);
$cheapestcp = min($fullratecp);
if ($cheapestgp < $cheapestcp){
$cheapestservice = array_keys($fullrategp, min($fullrategp));
$cheapestprice = $cheapestgp;
$cheapestpackage = "";
}else{
$cheapestservice = array_keys($fullratecp, min($fullratecp));
$cheapestprice = $cheapestcp;
$cheapestpackage = $packagecode;
}
//carrier
$cheapestcarrier ="";
if (str_contains($cheapestservice[0],'USPS')){$cheapestcarrier = 'USPS';} elseif (str_contains($cheapestservice[0],'UPS')){$cheapestcarrier = 'UPS';} elseif (str_contains($cheapestservice[0],'Fedex')){$cheapestcarrier = 'Fedex';}
return [$cheapestservice[0],$cheapestprice,$cheapestpackage,$cheapestcarrier];
}
function GetWarehouseLocation($warehouseid,$theapikey){
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://ssapi.shipstation.com/warehouses/" . $warehouseid ,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => array(
"Host: ssapi.shipstation.com",
"Authorization:" . $theapikey,
"Accept: application/json"
),
));
$response = curl_exec($curl);
curl_close($curl);
$resjson = json_decode($response,true);
$whpostalcode = $resjson['originAddress']['postalCode'];
return $whpostalcode;
}
?>
- December 15, 2021
100% agree. I requested this as well and hope it will be added in the future!
- January 6, 2022
Hi @gabe and others,
I actually developed a tool that allows you to do this in Shipstation. It's basically a tool that sits on top of your Shipstation and will automatically select the cheapest carrier / package type based on the conditions that you set.
It's really easy to set up. You can check it out at www.stationplus.co
Let me know if that helps!
Shawn
- January 11, 2022
With current transportation challenges, we need to be able to see the cost of two shipping methods to compare the prices as sometimes the difference is so small that we will choose the more expensive to ensure a quicker delivery. Seeing the approx. delivery dates would be nice as well, but not as crucial.
- Employee
- January 26, 2022
Hello!
Thanks to everyone for your patience. We are currently in a user testing and feedback phase for the first iteration of this feature and plan to release it to everyone early in 2022 (hopefully by the end of March). If you are interested in using the beta version, please respond to this thread to indicate so and I'll add you to the next group of users it will be enabled for!
Enter your E-mail address. We'll send you an e-mail with instructions to reset your password.
Scanning file for viruses.
Sorry, we're still checking this file's contents to make sure it's safe to download. Please try again in a few minutes.
OKThis file cannot be downloaded
Sorry, our virus scanner detected that this file isn't safe to download.
OK