Success of the businesses rely on developing a strategy to retain loyal customer-base. To attract and retain loyal customers, store owners add shopping cart price rules in Magento 2 to facilitate users with discounts.
People love discounts, and to attract potential buyers and existing customers, Magento 2 store owners implement the strategy to offer personal coupons which expire after a single use.
However, in Magento 2, if a customer places the order using the personal coupon code and cancels the order due to some reason like failed payment, reconsidering product options, etc; the coupon code gets expired. Now, when the same customer tries to reorder by using the personal coupon again, the coupon code becomes invalid as it’s already used once.
Store owners should consider this issue as a negative impact on shopping experience of their customers and must restore coupon code after order cancellation in Magento 2. This way, the customer can get benefit of discounts they are offered even after the order cancellation.
Follow the below solution to restore coupon code after order cancellation in Magento 2.
Programmatic Solution to Restore Coupon Code after Order Cancellation in Magento 2
1. Create registration.php file at Vendor\Extension\
<?php \Magento\Framework\Component\ComponentRegistrar::register( \Magento\Framework\Component\ComponentRegistrar::MODULE, 'Vendor_Extension', __DIR__ );
2. Create module.xml file at Vendor\Extension\etc\
<?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> <module name="Vendor_Extension" setup_version="1.0.0"> </module> </config>
3. Create events.xml file at Vendor\Extension\etc\
<?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd"> <event name="sales_order_payment_cancel"> <observer name="observer" instance="Vendor\Extension\Observer\Observer"/> </event> </config>
4. Create Observer.php at Vendor\Extension\Observer\
<?php namespace Vendor\Extension\Observer; use Magento\SalesRule\Model\Coupon; use Magento\SalesRule\Model\RuleFactory; class Observer { protected $couponModel; protected $rule; public function __construct( Coupon $couponModel, RuleFactory $rule ) { $this->couponModel = $couponModel; $this->rule = $rule; } public function execute($observer) { $event = $observer->getEvent(); $order = $event->getPayment()->getOrder(); if ($order->canCancel()) { if ($code = $order->getCouponCode()) { $coupon = $this->couponModel->create()->load($code, 'coupon_code'); $coupon->setTimesUsed($coupon->getTimesUsed() - 1); $coupon->save(); if ($customerId = $order->getCustomerId()) { if ($customerCoupon = $this->rule->create()->load($coupon->getId())) { $customerCoupon->setTimesUsed($customerCoupon->getTimesUsed() - 1); $customerCoupon->save(); } } } } $urlInterface = \Magento\Framework\App\ObjectManager::getInstance()->get('Magento\Framework\UrlInterface'); return $urlInterface->getCurrentUrl(); } }
Voila! the coupon can be applied again!
Please do consider sharing this post with Magento Community via social media.
Thank you.