Customer Selection Between Pickup, Delivery, and Shipping

I manage a website for a florist in New York. I built a SnipCart integration into the site so that she could process flower orders for both pickup (from her studio) and local delivery. I did this by re-naming all shipping fields as “delivery” fields and creating a singular shipping option called “delivery.” Customers select between two radio buttons (pickup or delivery) when adding an item to their cart, and this selection, in turn, designates the product as either non-shippable (if pick-up) or shippable (if delivery). Until now this florist has served only the New York area, so this little workaround was perfectly fine, but she is now additionally interested in offering certain products (ceramic vases, for instance) that can be shipped anywhere, domestically or internationally. For clarity, we’ll call these shippable items “goods,” while everything else that must adhere to the local pickup/delivery binary we’ll call “flowers.”

What I need to figure out is something that, as closely as possible, resembles the following system:

What I need to figure out is something that, as closely as possible, resembles the following system:

The user selection of pickup, delivery, or shipping happens only at the level of the cart—not per-item.

If the cart contains only goods, any of these three options are available to them.

  • Pickup
  • Delivery (only if address is within New York)
  • Shipping (one domestic option one international option)

If the cart contains only flowers, only pickup and delivery are available to them—not shipping.

  • Pickup
  • Delivery (only if address is within New York)

If the cart contains both flowers and goods, only pickup and delivery are available to them—not shipping.

  • Pickup
  • Delivery (only if address is within New York)

To make a more concise logic of the above rules: an entire cart can be picked up, delivered, or shipped, unless there are flowers in the cart, which then renders the cart unshippable.

Is there any way to create a system like this using SnipCart? Or something close to this? I am not quite sure what the best approach would be, as it seems the shipping options are somewhat limited.

See this discussion for details:

Basically, you can use custom shipping rates. Set the weight of the flower items to 100,000 or something huge and don’t offer a shipping rate for weights above that amount. Set the weights of the other items to their proper amounts and offer shipping for those. You can define the different shipping options as pickup, delivery, etc. and localize them as necessary. Not sure if you can localize down to the city level, though, as I haven’t tried that.

1 Like

Hey Billy—thank you for the response! I think this is a great workaround.

I did end up having a great discussion with Sébastien Lemieux about this and ended up settling on the following solution, per his advice. Reproducing here so others can reference as needed.

So what I did was build the following code into my button script, so that when a toggle called ‘shippable’ is switched on from the CMS, the given product is assigned the data item category ‘goods’.

<?php if($page->shippable()->toBool() === true):?>
data-item-categories="goods"
<?php endif?>

Then I went ahead and created five custom shipping methods, as Sebastien suggested, including a duplicate for studio pickup. They are as follows:

  • Domestic Shipping (United States)
  • International Shipping (worldwide—not localized)
  • Local Delivery (New York only)
  • Studio Pickup (New York only)
  • Studio Pickup (worldwide—not localized)

And then finally I modified the template override sample Sebastien provided (linked above) to include the following condition. This is effectively a conditional on a for loop through all shipping methods, displaying each given method to the user only if the method does not have the word “Shipping” in its title, or if all products in the cart are goods, in which case all possible shipping methods (contingent upon location) are displayed.

v-if="!rate.description.includes('Shipping') || cart.items.items.every(i => i.categories.some(c => c == 'goods'))"

This took a little tinkering to get just right, as the vue.js syntax wasn’t super familiar to me, but in the end it seems like an especially stable solution. Hope it may prove helpful for other folks here too.

1 Like