Simple Commerce Logo


If you're selling physical products on your store, you'll need a way to ship those products to your customers. Thankfully, Simple Commerce has an easy way to create custom shipping methods for your store.

Every store can have any number of shipping methods. For example, you could use one shipping method for 1st Class mail and others for 2nd and 3rd class mail.


Shipping Methods can be configured on a site by site basis. This means you could have different stores for each country you sell in and for each of those countries, you could have different shipping methods.

1'sites' => [
2 'default' => [
3 // ...
5 'shipping' => [
6 'methods' => [
7 \DoubleThreeDigital\SimpleCommerce\Shipping\StandardPost::class,
8 ],
9 ],
10 ],

Similarly to the way you configure gateways, it's just an array of shipping method classes. You can register as many as you need.

Creating a shipping method

Simple Commerce doesn't come with any shipping methods out of the box so you'll need to write your own. We do, however have a command you can use to generate the boilerplate for a shipping method.

1php please make:shipping-method YourNewShippingMethod

That command will create a Shipping Method class in your app\ShippingMethods folder. It'll look something like this:

3namespace App\ShippingMethods;
5use DoubleThreeDigital\SimpleCommerce\Contracts\Order;
6use DoubleThreeDigital\SimpleCommerce\Contracts\ShippingMethod;
7use DoubleThreeDigital\SimpleCommerce\Data\Address;
9class FirstClass implements ShippingMethod
11 public function name(): string
12 {
13 return 'Name of your shipping method';
14 }
16 public function description(): string
17 {
18 return 'Description of your shipping method';
19 }
21 public function calculateCost(Order $order): int
22 {
23 return 0;
24 }
26 public function checkAvailability(Address $address): bool
27 {
28 return true;
29 }

Here's a quick explanation of what each method does.

  • name: Should return the name of your shipping method (will be shown to customers)
  • description: Should return a description for your shipping method
  • calculateCost: This method should be where you return the cost of the shipping, based on the order's entry data.
  • checkAvailability: This method is where an Address object is passed in and you should return a boolean of whether or not you ship to that location.


Shipping Methods can be configured on a site-by-site basis, helpful for if you have different version of your store for different countries.

1'sites' => [
2 'default' => [
3 ...
5 'shipping' => [
6 'methods' => [
7 \DoubleThreeDigital\SimpleCommerce\Shipping\StandardPost::class,
8 ],
9 ],
10 ],

The methods array should contain an array of Shipping Method classes, with the ::class syntax.


During the cart/checkout flow, you'll want to do 2 things: first, let the customer enter their shipping address for the order and secondly, let the customer select the shipping method you want to use for the order.

Let's start with the letting the user enter their shipping address. In our starter kit, we have this on the initial cart page.

1{{ sc:cart:update }}
2 <input type="text" name="shipping_name" placeholder="Name" value="{{ old:shipping_name }}">
3 <input type="text" name="shipping_address" placeholder="Address" value="{{ old:shipping_address }}">
4 <input type="text" name="shipping_city" placeholder="City" value="{{ old:shipping_city }}">
5 <input type="text" name="shipping_region" placeholder="Region" value="{{ old:shipping_region }}">
6 <select name="shipping_country" value="{{ old:shipping_country }}">
7 {{ sc:countries }}
8 <option value="{{ iso }}">{{ name }}</option>
9 {{ /sc:countries }}
10 </select>
11 <input type="text" name="shipping_zip_code" placeholder="Postal Code" value="{{ old:shipping_zip_code }}">
13 <button type="submit">Update Shipping Address</button>
14{{ /sc:cart:update }}

When submitted, that form will fill in the appropriate address fields.

Hot tip: You can also do billing_name, billing_address, billing_city etc to allow the user to update their billing address.

After the customer has entered their address we can find available shipping methods for them and allow them to select which one they'd like to use. Again, we can use the {{ sc:cart:update }} tag to manage this. We also do this on our starter kit.

1{{ sc:cart:update }}
2 <p>Please select a shipping method for your order.</p>
4 <select name="shipping_method" value="{{ old:shipping_method }}">
5 <option value="" disabled selected>Select a Shipping Method</option>
6 {{ sc:shipping:methods }}
7 <option value="{{ handle }}">{{ name }} - {{ cost }}</option>
8 {{ /sc:shipping:methods }}
9 </select>
11 <button type="submit">Select Shipping Method</button>
12{{ /sc:cart:update }}

After the customer has submitted that form, Simple Commerce will use that shipping method and update the order totals.