Vouchers, Discounts and Credits

At the mini delivery team gathering we talked through a lot of the logic around discounts, vouchers and credits to come up with a pathway to achieving everything we need from this kind of functionality. I’m putting this in Discourse as there is a bit of background to communicate to the community. I will move over the Wishlist afterwards but I wanted to try and explain some of the curliness of these features in one place.

Terminology

Codes refer to codes for vouchers and discounts that can be applied at checkout.

Credits refer to customer balances that can be used at checkout

Background

We explored the potential implementations of vouchers and discounts, looking at the kinds of ways this could be calculated and ways that usage could be scoped. It is a complex beast as:

  • Codes could apply to all shoppers across OFN, all shoppers of an enterprise, or a single shopper
  • Codes can be time limited or permanent
  • Codes can have a single use b a shopper or could be used multiple times
  • Credits could be usable as a partial or full payment to an order
  • Credits could be a kind of refund on an order or could be added independent of any order
  • Vouchers could also be used as a partial refund on an order, though this requires quite a bit of manual setup by the enterprise and hence is not a great solution in short food supply chains.

This complexity in description is equally relevant in the complexity of implementation, so you can see this is not the most simple of topics.

What already exists

1. Simple Customer Credit

Paying in full with credits exists in a basic form now. Hub managers can add additional payments to any order. They can also create Products like ‘Add Credit’ that shoppers can buy in a normal shop. If the hub manager then cancels that line item the Shopper will be in credit. Using a payment method called ‘Pay with Credits’ the shopper can checkout. shoppers can see their balance in /accounts. There is a manual task to check if any shoppers’ balances are running low and notify them, meaning this is not a perfect implementation by anny means. However this simple function exists in OFN now.

2. Discounts and Vouchers

Right now discounts can be applied to specific Order Cycles and to specific Customers using negative fees. These negative fees seem to work reasonably well throughout the system, being mostly handled in reports. They do have a few drawbacks eg the discount is applied before the enterprise fees are added, making for some confusing calculations. However, many MCFEs are using this functionality now to offer discounts.

What does not exist

1. There is no way to offer a code for use at checkout and this is much wanted.

Assumptions about codes:

  • They will be available for anyone to use who has the code eg they can’t be tagged to customer. Use the existing functionality for codes that are specific to customers (refactorring the experience for the user will be a tech debt task, read on).
  • They could be single use or multiple use. Multiple use is simpler to implement but not overly useful for the shopper, so multiuse might be an early release under a feature toggle for enterprises.
  • They will have a date limitation eg start date and end date.
  • They will use the existing fee calculators. We know these work for this purpose. While they are tried, they are poorly tested in the negative use cases. Hence part of this work will be adding specs for the negative cases. We’ll also want to test the implications to reports.

2. Checkout with credits is a poor experience

Assumptions about credits:

  • Shoppers need to see their balance at the point of checkout when paying with credits.
  • Paying in full with credits is far easier to implement than paying partially with credits. However, credits will not be useful functionality for the purposes of refunds until partial payments can be made. Partial payment with credits effectively means paying with two payment methods at checkout. This is quite a complex piece of functionality to implement but will provide big user value in the simplification of refunds to shoppers for missing products etc.

Proposal for Implementation

1a: Code at Checkout

Funded Feature

  • Shoppers can enter a code at checkout. It can be used once per user and isn’t scoped to specific users (anyone with the code can use it)
  • Hub managers can create codes in backoffice with the standard OFN calculator functions and date limitations.

1b: Migrate existing discounts functions

Tech Debt

  • Use the same implementation as now (negative fees and tagging)
  • Ensure the negative fees create an error when applied as Enterprise fees
  • Move the functionality to the same area as the discount codes and ensure a consistent UX and UI

2a: Pay in full with credits at checkout

Funded Feature

  • Create a new payment method that shows the customer balance and allows the shopper to use this balance on checkout.
  • Can be turned on and off at enterprise level
  • When a balance of less than the order total is remaining and the enterprise has ‘Pay with Credit’ enabled, then the shopper sees the Payment Method at checkout but it is greyed out.

2b: Partial payment with credits at checkout

Funded Feature

  • The change means enabling shoppers to pay with two payment methods at checkout.
  • The Payment Method page in checkout would need to know the order total and recalculate after the balance has been reduced
  • We would need to be sure that negative fees on Payment Methods were disabled before implementing this.
  • This would also need to play nice with Codes, which would be messy in our new split checkout format.

Next Steps

  1. Agree that the above proposed implementation is the way to go.
  2. In order to estimate 1a and 2a we’ll need some simple UX mocks so we can do a front end estimate. This next step will be preparing the high level spec ready for estimating
  3. With rough estimates we can find the contributing instances and partners and raise the funds
  4. Then we can set about creating issues and prioritising for delivery

This is awesome - thanks @lin_d_hop and team!