How-to: free shipping or delivery (updated for ".total")

This requires calculations, which are available on the Pro and Agency plans.


Sometimes, you want to charge a delivery or shipping fee based on the amount that a customer has spent. This is a well-known scheme that we see frequently when it comes to food delivery and online shopping.

However, as of time of writing, there is not a direct way to implement this in a way that is as clean as possible from the customer’s point of view.

The direct approach


There are a couple simple ways we could do this:

  • add a single custom pricing rule that adds a set fee if Price is below a certain amount
  • add two custom pricing rules where we (1) add a set fee if a question is answered, and (2) subtract that fee if Price is above a specified threshold
Rules How to implement
1 Add a set fee if Price is below a specified amount
2 (1) Add a set fee if a specified question is answered, and (2) subtract that fee if Price is above a specified threshold

1-rule direct approach

If we do this, the price for the form will be set to the fee right when the customer loads the form. This doesn’t make for a very good user experience (UX) since no one thinks they’ll be charged anything without making some sort of selection first.

While you could prohibit anyone ever actually paying the fee without purchasing an item by making the product question(s) on your form required, it still may throw customers off. Throwing customers off means potentially lost sales.

2-rule direct approach

This one seems like it could be a winner at first glance. It sounds reasonable enough. We get rid of that UX issue from the above approach by only adding the fee if something is selected. Then, we subtract it if the order reaches the correct amount.

So, what’s wrong?

Well, what if you have multiple product questions? If you only make a rule to add a fee if one of them is answered, it won’t add a fee if the others are answered instead.

For example, say you offer breakfast, lunch, and dinner items in separate questions. If you add a fee if anything in breakfast is selected, that works fine if someone always orders at least one thing in breakfast. But, what if someone only orders lunch? No fee is added. That’s not right.

You might think: Well, then add a rule for each question! Someone could be charged triple the fees if they ordered from breakfast, lunch, and dinner items, then.

We also have another issue. Say you have a $50 order minimum for free shipping and shipping is $5. Using this approach, if someone orders $45 of items, our custom pricing rules will add $5 (the fee) for not reaching the order minimum.

But, we have another rule that subtracts the fee if the minimum is reached. However, the Price does not discern between subtotal and total (that is, subtotal + fees + surcharges + taxes + tip). It just counts everything up and applies the rules. So, the Price would see $45 + $5 = $50 and then subtract the fee since the Price hit the minimum. That is, it calculate $50 - $5 = $45. We told it to do this and it happily obliged. So, someone just got free shipping without buying enough stuff!

Abusing custom pricing rules (or, the indirect approach)


While custom pricing rules were not necessarily intended to get rid of the automatic pricing calculation done by the form, it does work for that purpose.

What we’re going to do here is:

  • Calculate our own subtotal
  • Wipe the automatic pricing done by the form
  • Determine our delivery or shipping fee
  • Calculate the new total (subtotal + fee)
  • Add the new total to the form’s Price

That’s quite a bit of stuff and it can get quite tedious if you have a lot of products. Do note that this solution isn’t very scalable, so try to implement it once you’re done finalizing the products you’ll be offering on the form. You can certainly edit the calculations after the fact, it’ll just become quite annoying if you have to do this repeatedly, especially since this introduces that much more opportunity for introducing typos that cause your calculation to come to a crashing halt.

Calculate our own subtotal

Update!
You’re in luck — we no longer need to do this by hand as the total associated with a given product question is now exposed to us directly in calculations. You can view the old, tedious method in the collapsed section at the end of this section if you’re curious.

Now, you can access the total using

{{ product_question_key.total }}

Yup. That’s seriously it. That’s significantly less work than the old method. If you have multiple product questions, just add them up their totals to get your subtotal now. Super easy.

subtotal = {{ q1.total }} + {{ q2.total }} + {{ q3.total }} + ...
The old, tedious method

This is the tedious part. After we handle this, we’re just gonna copy and paste it whenever we need it.

Each product question will have its own pre-fill key. Then, each product in that question will have a SKU. SKUs have a default value that can be changed manually or by importing your product list with populated SKUs.

The general format we’ll be using is {{ question_key.quantities.sku }} * price; where question_key is that product question’s pre-fill key, sku is an item’s SKU, and price is the price associated with that SKU. We will be doing this for every single product on your form.

Let’s suppose we have the following items in a single question:

Pre-fill key SKU Price
rht67 001 2.10
rht67 002 2.50
rht67 003 2.99
rht67 004 4.99
rht67 005 3.99

Let’s now create a calculation to get our subtotal. We’ll call it subtotal and let’s assume these are all scones so we have something consistent to refer to them as.

scone1 = {{ rht67.quantities.001 }} * 2.10;
scone2 = {{ rht67.quantities.002 }} * 2.50;
scone3 = {{ rht67.quantities.003 }} * 2.99;
scone4 = {{ rht67.quantities.004 }} * 4.99;
scone5 = {{ rht67.quantities.005 }} * 3.99;

subtotal = scone1 + scone2 + scone3 + scone4 + scone5;
subtotal;

Above, we gather the number selected for each item and multiply it by its price. If none are selected, that’d just be multiplying by 0, which is 0. Then, we sum all of those individual sums to get the subtotal; that is, the amount we’re going to charge the user before accounting for fees, surcharges, taxes, or tip.

This works similarly when you have multiple questions, too. You’d simply sum the items for each item in a question like we’ve done here for each question that you have products for and then sum those sums to get the subtotal across multiple product questions.

Wipe automatic pricing done by the form

Now, we’re going to apply a custom pricing rule to make sure the form isn’t doing the pricing for us. We want it to be completely ours, so we need to wipe it. By default, the form basically does what our calculation does: it takes each item, multiplies its quantity by its price, sums each of those calculations, and then adds that amount to the form’s Price.

So, let’s add a custom pricing rule from Configure > Payments > Custom pricing rules:

When subtotal is answered then - answer

Note: You are setting the option is answered for the rule, not is and then typing in answered.

This is what will actually take our calculated subtotal and remove it from the form’s Price.

Determine our shipping or delivery fee and calculate the total

This is going to be another calculation. Let’s call this one total since we’ll determine the fee and then add it to the subtotal to get our overall total in one go.

Copy and paste your entire calculation that you used for subtotal into this calculation, but delete the subtotal; at the bottom.

Next, add the following to the bottom of your calculation, or similar:

delivery_fee = IF(AND(subtotal > 0, subtotal < 50), 5, 0);

total = subtotal + delivery_fee;
total;

This example assumes that we’re going to charge a $5 fee if the order is less than $50 and give free shipping or delivery if the order is above $50. We also check that subtotal is greater than $0 since we wouldn’t want to charge a fee to someone who isn’t ordering anything.

Add the new total to the form’s Price

We’re going to add another custom pricing rule here:

When total is answered then + answer

This will add our total, which includes the shipping or delivery fee. (Don’t get too caught up in “includes the […] fee” as the fee is $0 if nothing is ordered or the threshold is met.)


Checkout label

You can specify a checkout label in the custom pricing rules section. Conveniently enough, it will show the following information on separate lines if the information is applicable (at least for Stripe, which is what I tested it on):

  • Each unique item, its quantity, and the total cost for the quantity selected
  • Checkout label for your custom pricing rules (blank if you didn’t enter one, but still a line item)
  • Processing fee
  • Tax

What’s even more convenient is that the price associated with your label will be the difference between the form’s calculated product total and your custom pricing rules.

So, for example, if you name your label “Shipping”:
shipping_line_item

That’s really nice as you can show your customers how their shipping was charged.


What if I have a lot of products? That’s going to be a lot of work to write out all those variables.

You’re right — it is a ton of work. A good way around this is to export your products (if you initially created them on Paperform) or use the .csv you already have for your products to create all those lines in the calculation easily. See the collapsed section below to learn more about making this easier on yourself.

Using a spreadsheet to construct the calculation for me

Note: you’ll want the pre-fill key you’ll be using for each question.
If you haven’t already imported your .csv into Paperform, you either can do that and pull the generated pre-fill key or decide on a custom pre-fill key for each question and then change each question’s custom pre-fill key to match what you have.

So, what I did was organize my data in my spreadsheet:

number category SKU price key line
1 scone 001 2.10 rht67 CONCATENATE()
2 scone 002 2.50 rht67 CONCATENATE()
3 scone 003 2.99 rht67 CONCATENATE()
4 scone 004 4.99 rht67 CONCATENATE()
5 scone 005 3.99 rht67 CONCATENATE()

For the CONCATENATE():

=CONCATENATE(<category_cell>, <number_cell>, " = ", <key_cell>, ".quantities.", <SKU_cell>, " * ", <price_cell>) 

Then, repeat the cell’s value based on a pattern using the fill handle. It’ll construct all those lines of the calculation for you that are like

scone1 = {{ rht67.quantities.001 }} * 2.10;

You can do this similarly for multiple product questions, changing the number, category, and key. Of course, the SKU and price will also be changed, but those are different for every item.


In closing

Now, that’s quite a workaround. But, it gets the job done and lets you customize pricing quite a bit more. You can even do more complex things like factor in shipping of different speeds, calculate quantity discounts, and more.

Post any comments here if you have any confusion about any of the steps, need some additional help, or have any suggestions.

4 Likes