Why live shipping calculations for ecommerce are the bane of my existence

I’ll be frank: I don’t really like ecommerce. I’ve floated for most of my 23-year career in web development in the fantasy of a Platonic ideal of an online world: bytes streaming from point to point on a perfect network. No messy complexities of the physical world to concern me.

Well, obviously none of that is true. And I’ve been dealing with ecommerce in some form or another for at least 20 of those 23 years. But I still find the nitpicky details of sales tax and shipping logistics both mind-numbingly dull and infuriatingly (seemingly pointlessly) complex.

Which brings me to the crux of today’s rant. Bringing simplicity to all of this… or, at least, to the part I have to deal with.

Granted, I am not an accountant, and I don’t have to deal with balancing my clients’ numbers at the end of the quarter. But from my perspective, there are some simple solutions to the fact that calculating shipping sucks.

These days I deal mainly with WordPress, and therefore with WooCommerce. There are a lot of extensions to WooCommerce now for live shipping rate calculations. You can pay an annual fee for tools that connect you to shippers’ APIs to give you exact shipping rates. And all you need to do is:

a) determine exact weights and dimensions of all of your products,

b) figure out exactly what types of boxes/packages you’re going to use (and determine their exact weights and dimensions), and

c) plug all of those numbers into WooCommerce, and also

d) decide which of those types of packages are applicable to which products, create the appropriate Shipping Classes, and apply them to the corresponding products; then

e) set up Shipping Zones for each part of the world you’ll ship to,

f) add shipping methods in each of those zones for each of the shippers you’re working with,

g) go into each shipper, in each Shipping Zone, and select from the dozens of shipping services each shipper offers (although you might have to do this multiple times, if you want to restrict the methods you offer based on your Shipping Classes), then

h) test adding these products to your cart, enter an applicable shipping address, and see if you get the right shipping charges… or any shipping charges at all… because you very likely won’t, because for instance you may not realize that

i) WooCommerce Services no longer offers free access to USPS live shipping calculations for new sites created after WooCommerce 3.6, and you now need to buy a separate extension for $79/year to do that. But the free plugin won’t give you any indication that this is the case; it will still show you all of the shipping methods in the configuration pages, it just won’t give you back any rates on the checkout page, and you won’t have a clue as to why until you stumble upon a small note to this effect on the WooCommerce documentation website.

In case you didn’t guess, I just went through all of this today. And this was on a site that only has 7 SKUs!

Of course, there’s a different way to approach this. You could, instead:

a) offer flat-rate shipping.

Obviously it’s not quite that simple. But here’s the thing: there’s no law saying you can’t charge customers more for shipping than it costs you. That’s the whole idea behind “shipping and handling.” In fact, whether you’re doing the fulfillment yourself, or you’ve hired an outside fulfillment vendor, you’re paying more to ship those products than the shipper’s calculated rate anyway, so you should charge more.

Here’s what I recommend.

First, decide on a shipping method. Or maybe a few. Depending on what you sell, you might want to use USPS Media Mail (if it’s applicable). Otherwise, you’ll most likely want to offer two shipping methods: a) ground (cheap but slow) and b) 2-day air (more expensive but reasonably fast). You choose the vendor you like best: USPS, UPS, FedEx, some guy they call “Crusty Pete” with a rusty old pickup truck, etc.

Find out approximately what it will cost, on average, to ship each of your products, by each of these methods. (This is a good use for Shipping Classes.) Then tack on an arbitrary “handling” fee, say $1 per item for ground and $2 per item for 2-day air.

Now, decide: do you want customers to see a shipping charge, or do you want to offer “free” shipping? My logic for this is relatively easy. You just need to balance these two considerations:

  1. People like to see free shipping.

  2. People don’t like to see ridiculously high prices for individual items.

If you are going to offer “free” shipping, you’re really going to take that approximated shipping cost for each item and add it to the selling price of the item itself. Does that make the price of the item seem exorbitant? If not, go for it. People like free shipping.

As long as the shipping price itself isn’t so huge that it causes people to balk when they see it on the checkout page, you can keep the item prices low and present the shipping charge there. Or, a mix: offer “free” ground shipping, included in the price of the item, and then at checkout give the option of “free ground shipping” or paid 2-day air, with the 2-day air prices set at whatever you determined they should be, minus the amount you had already rolled into the item prices for free ground shipping.

Flat-rate shipping isn’t literally flat rate, as in one fixed price no matter what you’re buying. Generally it’s a formula… a base price, plus a multiplier based on the number of items.

For instance, your flat-rate formula might be $5 base plus $2 per item. The customer buys one item? $7 shipping. Two items? $9 shipping. You just plug the formula into the settings, and the rest gets calculated automatically.

The whole purpose of having shipping charges at all is to cover your expenses. Paying an annual license fee for a live shipping calculator extension, plus paying a developer or consultant for their time in helping you wade through all of these complicated configurations, and troubleshoot the problems that crop up, only to end up charging customers exactly what you’re paying for shipping and not a penny more just ends up costing you money. And the fact that these extensions include an option to add on an arbitrary amount above the calculated rate gives the game away… You don’t have to charge customers exactly what you’re paying for shipping. You just need to cover your expenses.

Your time and (my) mental wellbeing are expenses too. As long as your accountant doesn’t get too frustrated with the variable amount of ancillary income you’re getting from the modest overage you’ve calculated into shipping and handling charges, free or flat-rate shipping is a much simpler and more manageable alternative to live shipping calculations.

iCloud Drive: Don’t do what I did!

Being deeply immersed in the Apple ecosystem, a couple of years ago I made a decision:

I’ll move all of my work files onto iCloud Drive!

I work (as in, write code and edit image files) mainly on my Mac. But I was seduced by the possibility of accessing all of my work files in a pinch on my iPad (which I still had at the time) or even my iPhone. Plus, since my files would be in “The Cloud”, I could even access them from another computer (or from my Mac when booted into Windows) if I needed to, by logging into my iCloud account from a web browser.

It seemed… so obvious. So perfect.

Umm… maybe not.

For the past two years, I have been constantly fighting with iCloud Drive. One of its signature features is that it can manage disk use on your Mac automatically, so as your hard drive fills up, it deletes files you haven’t used in a while, keeping them safely in the cloud while freeing up disk space on your Mac. And with my MacBook Pro sporting a (meager?) 256 GB hard drive, with 40-odd GB allocated for a Windows partition, and over 60 GB occupied by Logic Pro X sound samples, my drive is filling up constantly.

While this is great in principle, it is completely unworkable in practice for three interrelated reasons:

  1. If you have a large amount of data in play here (for me, it’s in the vicinity of 100 GB), iCloud Drive may get to a point where it is constantly transferring data. If you’re not on a gigabit fiber connection, this can both use up all of your Internet bandwidth and take ages.
  2. Because #1 is taking place constantly, if you do find yourself needing to grab one of those files that has been deleted locally (as indicated in the Finder by a cloud icon with a down-pointing arrow), you may find yourself waiting several minutes for the file to become available, even if it’s small (as in, under 1 MB).
  3. In an effort to make this all appear seamless to the user, the Finder represents cloud-only files as… regular files. But they’re actually just pointers with a hidden .icloud filename extension… as you’ll find if you ever try to perform Finder actions inside another program, such as syncing files to a web server using Transmit.

All of this might be tolerable if Apple gave you any control whatsoever over which files get deleted locally. But they don’t.

It gets worse.

What’s worse than getting stuck in this situation? Trying to get out of it. It’s like quicksand… the more you struggle against it, the faster and deeper you sink into it.

I made the decision earlier this week to extricate myself from the iCloud Drive nightmare, by buying a 250 GB SanDisk external SSD. First off, a little unpaid plug for this drive… it is awesome. It’s super light and small, seemingly at least as fast as the internal SSD in my MacBook Pro (in that I am able to transfer multiple gigabytes of data in seconds), and it even looks cool. I’m going to be using it all the time, so I’m actually considering putting adhesive Velcro on both it and the top of my MacBook Pro so I can keep it permanently attached. (Which says a lot about how much my regard for Apple has fallen lately — in the past I would never have sullied the exterior of an Apple laptop with something adhesive.)

So anyway, external SSD acquired, my goal was to start transferring my files from iCloud Drive over to the SSD.

Uh… good luck with that.

Because I’m now at a point where I have more than double the amount of data stored on iCloud Drive as I have available space locally, a majority of my files are now only in “The Cloud.” Ugh. Which means waiting for all of that data transfer stuff to happen. If only I could, somehow, bypass this broken process, I thought.

There has to be a way.

tl;dr Nope.

So, here’s the thing. I’ve been using iCloud Drive for the bulk of my cloud-based file storage, but I do use other services as well. I have Google Drive. I have Dropbox. I know how they work.

Specifically, I know that you can, y’know, like, select a folder and download the entire thing as a zip file.

So I thought to myself, I’ll just go to iCloud in a web browser and do that! Download the whole friggin’ thing as a big zip file, or maybe a few zip files, and be done with it.

Nope.

For whatever reason, iCloud doesn’t let you do that. Probably because of the whole seamless “It just works” Kool-Aid drinking song everyone in Apple land has been singing. (Myself included, mostly.)

You can only download individual files, not folders, from the iCloud web interface. It does let you select multiple files at once, but only within one folder.

Check out this delightful thread full of know-it-all asshats whose response to a legitimate question — why doesn’t Apple allow this thing that every competing service does? — is to challenge the validity of the question and the intelligence of the questioner. (That thread is now closed so I’ve just opened my own new thread on the topic. Watch this space for trolls!)

There. Are. Plenty. Of. Reasons. A. Person. Might. Have. For. Needing. To. Do. Something. That. You. Have. Not. Previously. Considered. Stop challenging their premises and answer their question, or shut the hell up.

Whew.

I ended up “solving” the problem by resigning myself to the fact that it wouldn’t be completely solved. So instead I took the drastic approach of temporarily logging out of iCloud completely, just so I could strand the files I did have saved locally, and copied them to the SSD.

Then I logged back into iCloud Drive and tried to get it to stop syncing my files by unchecking the Desktop and Documents Folders option.

The only problem is, I didn’t have my work files in those folders. I had them in a separate top-level folder in the iCloud Drive that I created myself. Because, you know, you can do that and it didn’t seem like a crazy idea or anything.

It was.

I discovered this morning that even though I had done all of this and tried to purge the nightmare of constant iCloud Drive syncing from my Mac life, once I had logged back into iCloud, the Mac went right back to quietly, constantly, syncing that iCloud Drive data on my Mac. As I type this, I have a Finder window open to my iCloud Drive and in the status bar it says “downloading 120,079 items (36.14 GB of 48.66 GB)”. Fun!

So, my new plan for today is to watch that window, and as the little cloud icons next to individual folders goes away, I’m copying those folders to my SSD and then deleting them from iCloud. My assumption is that as I do this, I am freeing up more local space and iCloud will continue to download the remaining items, and eventually I’ll have everything transferred over.

But please… do yourself a favor and don’t do what I did. iCloud Drive is not suitable for professional use.

Vegetarian Swedish “Meatballs”

(Another day, another blog post with a vegetarian recipe! Again, I’m not turning this into a food blog, but this is just something I’ve been meaning to write up for a while, and I made it last night so the timing is right.)

I was going to just put “meat” in quotes in the title, but (a) I was thinking about SEO (yes, I’ve become that person) and (b) I realized that, for this recipe, “balls” really needs to be in quotes just as much as “meat”. You’ll see why when you cook them. Let’s just say neither “meatmuffins” nor “meatpucks” really works, for obvious reasons. I seem to keep mistyping the word as “metaballs” which I actually think is quite appropriate. But, you know… SEO.

Also just a word of caution… this is definitely not vegan, and it’s not particularly “healthy”. But it’s a bit of that “hygge” everyone’s after these days (even though that’s Danish).

I’ve been eating vegetarian/pescatarian for the last 5 1/2 years, but I’ve been a Minnesotan of mixed Scandinavian descent my entire life. So, yes… I’ve been quite familiar with Swedish meatballs for a long time. Well before Minnesota finally got an IKEA store in the mid-2000s.

In fact, I’ve made the meat variety of Swedish meatballs so many times that I still have the recipe memorized, even though I haven’t tasted them since 2013. Granted, my kids are not vegetarians, so I still have to occasionally make the traditional version for them. But last year I finally cracked the code on a vegetarian version. For a while I’d just use general-purpose frozen vegetarian “meatballs” and cook them in a vaguely Swedish cream sauce. I even used “GRÖNSAKSBULLAR” from IKEA. (Why does IKEA do everything in all-caps? It’s awfully shouty for mild-mannered Swedes.) They’re not bad… but they’re not right for this dish, either.

There’s a certain chunky texture that proper Swedish meatballs need, and the processed smoothness of frozen “meatballs” — plus the lack of the correct spices — just won’t cut it. So I turned to another processed frozen meat substitute… “crumbles”.

Yes, the secret to my vegetarian Swedish “meatballs”, if I’m being precise about it, is MorningStar Farms® Grillers® Crumbles™. (I copy-pasted that from their website to make sure I got all of the trademarks right.)

That, and a muffin tin.

This mixture isn’t as firm as one with ground beef, so you can’t shape balls by hand. That’s where the muffin tin comes in, as well as the slightly odd shape of the final product. We’ll be baking these instead of browning them in a skillet as with traditional Swedish meatballs.

This recipe also involves one of my favorite skills I have acquired as a cook: making a good sauce. Whether it’s gravy, béchamel, or whatever you want to call it, the principle is the same: 4 tbsp fat, 4 tbsp flour, 4 c flavorful liquid. Cook the fat and flour together for a minute, then gradually add the liquid, stirring constantly to absorb completely and keep the consistency smooth. Once you “get it”, it’s simple and awesome. But I rarely see it described correctly.

OK, enough Minnesota small talk. Let’s get cooking!

Vegetarian Swedish “Meatballs”

Makes 4 to 6 servings.

Ingredients

For “Meatballs” (a.k.a. Metaballs)

1/2 tbsp butter
1/2 tbsp vegetable oil
1 small(-ish) onion, very finely chopped; reserve 1-2 tbsp for cream sauce
1 12-oz pkg MorningStar Farms® Grillers® Crumbles™ or similar
3 eggs, lightly beaten
3 slices stale(-ish) bread, processed to fine crumbs
1 tsp (or so) freshly grated nutmeg
1/2 tsp ground allspice
1 tsp kosher salt
1/2 tsp freshly ground black pepper

For Cream Sauce:

2 tbsp butter
2 tbsp vegetable oil
4 tbsp flour
3 c vegetable broth
1/2 c milk and 1/2 c cream
(or just 1 c milk if you’re pretending this is healthy)
pinch of nutmeg
pinch of allspice
2 tbsp ketchup
(or 1 tbsp Worcestershire sauce if ketchup sounds too weird to you)
salt and pepper to taste
minced fresh dill or dried dill weed for garnish

Preparation

Stuff you’ll need to have ready before you start:

  • a large (12-inch), high sided skillet
  • a 12-cup muffin tin, greased and floured
  • a large mixing bowl
  1. Preheat oven to 375ºF.
  2. In large skillet, melt 1/2 tbsp butter with 1/2 tbsp oil over medium heat. Add the onions (except reserve), and cook about 3 minutes until softened. Stir in entire package of crumbles, cover and set to medium-low for 3-5 minutes. You’re just trying to thaw the crumbles, not cook them! Check periodically and break up big pieces as they thaw. Remove from heat as soon as crumbles are soft.
  3. Meanwhile, in a large mixing bowl, stir breadcrumbs into beaten eggs with nutmeg, allspice, salt and pepper. When the crumbles and onions are ready, add them and stir to combine thoroughly. Leave any remaining bits in the skillet as long as they’re not burned… they’ll flavor the sauce.
  4. Prepare your muffin tin by spraying with cooking spray and then dusting with flour. Shake out excess flour into the sink.
  5. Using a large spoon, scoop the mixture equally into the 12 cups of the muffin tin. Use the back of the spoon to smooth the mixture into rounded mounds inside the cups, but don’t press them too firmly. You just want them to stay together.
  6. Place the filled muffin tin on the center rack in the preheated oven and bake for 20 minutes. Remove muffin tin from oven and let cool.

    While the muffins are baking, you can start on the cream sauce or work on anything else you need to prepare, like potatoes or vegetables. The meatballs can rest on the counter for a while if needed.


  7. In the same skillet you used for the onion/crumble mixture, you’ll start on the cream sauce. Add your reserved onions, 2 tbsp butter and 2 tbsp oil and heat over medium-high heat. When the butter has melted and onions are translucent (or slightly browned on the edges, depending on your taste preference), add the flour and pinches of nutmeg and allspice, and whisk gently until completely absorbed and smooth, about 1 minute.
  8. Turn the heat to high and gradually add the broth to the saucepan, about 2-3 tbsp at a time. Constantly whisk the mixture gently (to avoid splashing), making sure the liquid has completely absorbed before adding more. As you do this the mixture will transform in appearance from grainy clumps, to pastry dough, to mashed potatoes, and finally a creamy smoothness.
  9. When all of the broth has been added, whisk in the milk and cream. Bring to a boil, then reduce heat to medium-low and simmer. Stir frequently to avoid sticking or burning on the bottom of the pan. Adjust heat if needed to keep a gentle simmer.
  10. After sauce has thickened slightly, add ketchup (or Worcestershire sauce) and whisk to mix thoroughly.
  11. Gently remove baked “meatballs” from muffin tin — you should be able to twist them slightly with your hand to loosen them from the cups — making sure not to break them apart. Add them into the simmering cream sauce and continue to simmer, stirring occasionally, about 10 minutes or until sauce has reached desired thickness. Add salt and pepper to taste.

Serve 2 to 3 “meatballs” per person with mashed potatoes and a generous amount of cream sauce sprinkled with dill, along with vegetables and lingonberry or cranberry sauce.

Vegetarian (Vegan) Chili

I don’t envision this turning into a food blog, but I’ve been eating vegetarian/pescatarian for about 5 1/2 years now, and I’ve gotten to the point where I rarely cook with recipes, instead relying on my experience and familiarity with the ingredients I’m using to make things “from memory.”

The thing is… I’ve gotten better as a cook, but I’m not that good. Some of the things I make can be hit-or-miss, since the quantities of ingredients and details of the cooking process are slightly different each time.

So, when I really nail something — which does happen from time to time — I think maybe it would be a good idea for me to write up a recipe, before I forget everything.

Last night I made a vegetarian chili, and was quite pleased with the results. Thus, here is the “recipe” (written up after the fact), mostly so I can remember this later.

Vegetarian Chili

Makes about 6 servings. (Unless you’re me, in which case it’s more like 4.)

Ingredients

For chili:

1/4 cup canola oil
1 small onion, finely chopped
1 red or yellow bell pepper (or 1/2 of each), finely chopped
2 cloves garlic, minced
2 tbsp chili powder
1 1/2 tsp cumin powder
1/2 tsp cayenne pepper
1/2 tsp oregano
1 28-oz can (or 2 14-oz cans) diced tomatoes (with liquid)
2 cups vegetable broth
1 tbsp maple or agave syrup
1 can chili beans, drained and rinsed
1 can black beans, drained and rinsed
salt and pepper to taste

For garnish:

minced cilantro
minced scallions
diced fresh cherry tomatoes
guacamole

Preparation

  1. In a large pot, heat oil over medium-high heat. When oil is hot, add spices (chili powder, cumin, cayenne and oregano) and stir for about 20 seconds, then add onion, peppers and garlic. Cook, stirring occasionally, until onions are translucent, about 5 minutes.
  2. Add diced tomatoes and their liquid and stir. Raise heat to high and bring to a boil. Pour in vegetable broth and syrup and return to boil.
  3. Stir in all of the beans and bring to a simmer. Reduce heat to low.
  4. Cook uncovered for at least 30 minutes, stirring occasionally. Pour in additional broth if chili is getting too thick. Season to taste with salt and pepper.
  5. Pour into bowls and garnish as desired.

Additional Notes and Suggestions

  • Quantities for spices are approximate. (And, honestly, I didn’t measure any of them besides the chili powder.) Adjust to suit your taste.
  • “Chili beans” is kind of a nebulous term. I used a can of Westbrae Natural Organic Chili Beans, which is a mixture of pinto, kidney and black beans. You can use any kind of beans, really, although I think white beans are too delicate in flavor for this. But when I think of chili I think of kidney beans or black beans. And honestly, kidney beans in large quantities don’t “agree with me”, so I went with straight black beans for the second can. I know a lot of people make chili with just black beans, but for some reason I find that a little boring.
  • Sometimes canned tomatoes have herbs like basil added. Be sure you’re getting plain tomatoes.
  • Corn is a nice addition, but we didn’t have any in the freezer last night. Add 1 cup of frozen corn at the same time as the beans.
  • This recipe is vegan, but if you eat dairy, you can garnish with sour cream or shredded sharp cheddar cheese instead of (or in addition to!) the guacamole.
  • For breakfast the next day, heat up a bowl of the leftover chili and top with a poached egg.

Fixing a redirect loop on WordPress sites with WooCommerce when converting the site to all-SSL

Best practice these days is to run sites on all-SSL, not just the parts of the site that “need” it. But not long ago, it was common to apply SSL only when it was absolutely necessary, because SSL encryption meant a performance hit. Not anymore.

You may find, if you’re trying to convert an existing WordPress / WooCommerce site to all-SSL, that reconfiguring your URLs, by using a tool such as interconnect/it’s super-slick, powerful (and dangerous) Search Replace DB tool, that once you’ve made the changes, your home page kicks into a redirect loop, indefinitely cycling between http:// and https:// versions of your URL.

WooCommerce may be to blame!

Specifically, a setting in WooCommerce called “Force HTTP when leaving the checkout”. Head on over to WooCommerce > Settings > Checkout and… um… check it out.

Simply uncheck that box, and, while you’re at it, uncheck “Force secure checkout” since it’s unnecessary on an all-SSL site, save your changes, and your home page should come back to live!