<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="/css/simple-atom.xslt"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title>Death.au's Domain posts tagged Shipping</title>
  <subtitle>Thoughts, stories and ideas.</subtitle>
  <link rel="self" href="https://death.id.au/tag/shipping/atom.xml" type="application/atom+xml" />
  <updated>2026-08-05T06:30:37Z</updated>
  <author>
    <name>Death.au</name>
  </author>
  
  <id>https://death.id.au/tag/shipping/</id>

  
  <entry>
    <title>Area Safe Products</title>
    <id>https://death.id.au/cv.21/</id>
    <updated>2026-03-25T00:00:00Z</updated>
    <published>2026-03-25T00:00:00Z</published>
    <content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><h1>Area Safe Products</h1>
<p>Area Safe Products sell road, traffic and public-safety equipment — bollards, wheel
stops, street furniture — across two brands: Area Safe Products and Astra
Street Furniture. Both storefronts run from a single CS-Cart backend.</p>
<p>I rebuilt their checkout and took it live in late March 2026.</p>
<h2>Three ways to buy the same thing</h2>
<p>Most eCommerce checkouts have one job: take the money. This one has three, because the
customers aren't all the same kind of customer.</p>
<p>A member of the public buying a wheel stop pays by card. A council or contractor
specifying street furniture wants a <strong>quote</strong>, not an order. An established trade
customer wants to place the order <strong>against their existing account</strong> and be invoiced.
Same catalogue, same cart, three completely different outcomes — and the sales team
works the quotes and account orders that come out the other end.</p>
<p>The complication was that none of this sat on standard data structures. Order type and
flow were carried on non-standard fields, layered over a
heavily modified and by-then deprecated multi-step checkout addon. It was not a
greenfield build; it was a rebuild threaded through several years of accumulated custom
code, which is the harder and far more common real-world problem. I ended up writing a
report for my director explaining <em>why</em> the checkout was so resistant to change, which
was as useful to the client as the code.</p>
<h2>What went into it</h2>
<ul>
<li><strong><code>swim_checkout_options</code></strong> — a custom addon managing order type and the branching checkout flow.</li>
<li><strong>A weight-and-freight rate engine</strong>, built and loaded via SQL across the <code>shippings</code>, <code>destinations</code> and <code>shipping_rates</code> tables, with GST applied per rate area.</li>
<li><strong><code>swim_forklift_charge</code></strong> — a custom addon that automatically applies a tailgate-unload surcharge when any item in the cart exceeds 80 kg. If you're buying something that needs a truck with a lift on it, the checkout works that out rather than the customer discovering it later.</li>
<li><strong>Stripe</strong> with daily settlement, plus Purchase Order and Quote payment methods.</li>
<li><strong>The Stair Nosing Calculator</strong> — a small HTML/JS widget on the product page. Stair nosing is sold by length and you need a specific quantity for a specific staircase, so the customer enters their measurements, the widget computes what they need, and it goes straight into the cart. The client built this with an AI tool and then asked me to hook it up to actually add items to the shopping cart.</li>
</ul>
<p>Later in the year I also spent time on the platform's reliability — the store had been
going down repeatedly, and tracking that down turned into a separate piece of work
involving PHP-FPM pool limits, memory saturation, and a fair amount of arguing with my
own monitoring about what it wasn't telling me.</p>
</div></content>
    <link rel="alternate" href="https://death.id.au/cv.21/" />
    <summary type="html">A three-path B2B checkout and freight engine, across two storefronts running from one backend.</summary>
  </entry>

</feed>