kongondo Posted May 5 Share Posted May 5 An example of how to use new discounts feature in Padloper 009 in the frontend. Important things to note: You can validate and apply discounts programmatically or by capturing details using your custom form. Padloper does not output a discount input since discounts are an optional feature. Padloper provides a discount API that allows you to validate, apply, invalidate, remove, etc. discounts from an order. 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 Discount validation failed Discount applied successfully 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. 1 Link to comment Share on other sites More sharing options...
Spinbox Posted September 10 Share Posted September 10 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? 1 Link to comment Share on other sites More sharing options...
kongondo Posted September 27 Author Share Posted September 27 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 More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now