Jump to content

Padloper 009: Discounts Feature


Recommended Posts

An example of how to use new discounts feature in Padloper 009 in the frontend.

Important things to note:

  1. You can validate and apply discounts programmatically or by capturing details using your custom form.
  2. Padloper does not output a discount input since discounts are an optional feature.
  3. Padloper provides a discount API that allows you to validate, apply, invalidate, remove, etc. discounts from an order.
  4. You can submit your discount code form to the server however you wish, i.e. ajax or non-ajax.

The example below applies a discount with code 'SAVE10'. This is a 10% whole order discount. The example uses htmx (ajax). The form is in the checkout page but the ajax endpoint can be a single place, e.g. your home page.

Example Apply Discount Form Screenshots

Discount form on checkout page

326010892_2024-08-31111613_apply_discount_003.png.04cd85bffc7b4ece26ba3e3f1af7ada3.png

Discount validation failed

220098758_2024-08-31103513_apply_discount_001.thumb.png.d79d8d7ea59ee9889be8147ffeaf5df5.png

Discount applied successfully

1982156970_2024-08-31105813_apply_discount_002.thumb.png.51f3a1a66159c3a55bbf34cadedd1ceb.png

Example Apply Discount Ajax Form Handling 

Please see the comments in the code.

Spoiler
<?php

namespace ProcessWire;

// part of checkout template file. (/checkout/ page)

// HANDLE HTMX AJAX REQUESTS
if ($config->ajax) {
	$out = "";

	/////////////////////////
	if (!empty($input->post->order_apply_discount_code)) {
		// HANDLE DISCOUNTS APPLY/REDEEMING
		// -----------------------
		$out = "";
		// HANDLE REQUIRED INPUTS FOR DISCOUNT: code, email and country

		// 1. code
		// CUSTORM FORM TEXT INPUT FOR DISCOUNT CODE ('order_apply_discount_code')
		$dirtyCode = $input->post->order_apply_discount_code;
		$code = $sanitizer->sanitize($dirtyCode, "text,selectorValue");
		// 2. customer email
		$customerEmail = $sanitizer->email($input->post->order_apply_discount_customer_email);
		// 3. customer country
		$customerShippingCountryID = (int) $input->post->order_apply_discount_customer_shipping_country;


		if ($code && $customerEmail && $customerShippingCountryID) {
			// GOOD TO GO: all required values are present

			// VALIDATE AND SET THE DISCOUNT TO THE ORDER IF VALID
			/** @var WireData $result */
			$result = $padloper->validateAndSetDiscount($code, $customerEmail, $customerShippingCountryID);
			// -------
			// prepare message

			if ($result->isValid) {
				// discount validation passed
				$discountType = $result->discountType;
				$discountValue = $result->discountValue;

				if ($padloper->isFixedDiscount($discountType)) {
					// FIXED DISCOUNTS
					$discountValueAsCurrency = $padloper->getValueFormattedAsCurrencyForShop($discountValue);
					if ($padloper->isFixedPerOrderDiscount($discountType)) {
						// fixed per order discount
						$message = "A discount of {$discountValueAsCurrency} will be applied on the order at checkout.";
					} else {
						// fixed per item discount
						$message = "A discount of {$discountValueAsCurrency} will be applied on each eligible item at checkout.";
					}
				} elseif ($padloper->isPercentageDiscount($discountType)) {
					// PERCENTAGE DISCOUNTS
					// @note: you can be more spefic, e.g. whole order percentage versus selected items percentage discount. See the API docs for discount methods in Padloper
					$message = "A discount of {$discountValue}% will be applied on eligible items at checkout.";

				} elseif ($padloper->isFreeShippingDiscount($discountType)) {
					// FREE SHIPPING DISCOUNT
					$message = "Free shipping will be applied at checkout.";
				} else {
					// BOGO DISCOUNT
					// TODO

				}

				// just in case this discount has already been applied to this order
				if ($result->isAlreadyApplied) {
					$message = "This discount has already been applied to the order. {$message}";
				}
			} else {
				// DISCOUNT VALIDATION FAILED
				// @note: $result->notice will give you the exact reason validation failed.
				$message = "Sorry, the specified discount cannot be applied to this order. Please amend your basket and/or your customer details.";
			}
		} else {
			// MISSING DISCOUNT CODE AND/OR CUSTOMER EMAIL AND/OR CUSTOMER SHIPPING COUNTRY
			$message = "Please ensure that you specify a discount code, your email address and shipping country";
		}

		// OUTPUT RESPONSE FOR HTMX
		// @note: currently this message replaces existing ones; you can change this using htmx attributes such as oob, target, etc
		$out .= "<p class='mt-3'>$message</p>";

	}
	// -----------
	echo $out;
	// exit;
	$this->halt();
}


// ---------------
// USUAL CONTENT

// Primary content is the page body copy
$content = $page->body;

 

Thanks.

  • Like 1
Link to comment
Share on other sites

  • 2 weeks later...

Thanks Francis,

Works wonderfully.

I noticed the flat amount is without tax. I would expect it to be included with tax. Both for the end user and the customer. Right now if I set 10,- off, it will actually be 12,1 off. Is this intended behavior?

  • Like 1
Link to comment
Share on other sites

  • 3 weeks later...
On 9/10/2024 at 9:54 AM, Spinbox said:

I noticed the flat amount is without tax. I would expect it to be included with tax. Both for the end user and the customer. Right now if I set 10,- off, it will actually be 12,1 off. Is this intended behavior?

Hey @Spinbox,

I am afraid I don't understand 😀. Could you please give me a complete example including whether shop prices include tax + whether the product you are testing with is taxable. Thanks. Please note that tax is applied on the final net price, i.e. after all discounts have been deducted. Secondly, if prices include tax and a discount is being applied, we first have to compute the price of the product without tax, then apply the discount on that net. Finally, we add tax to the final, discounted price.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...