Drupal Commerce 2: Apply Coupons from URL Arguments
If you decide not to enable the Coupon Redemption pane in your checkout flow, but still want to allow some customers to redeem their coupons somehow, you can allow them to be passed via a URL argument.
Two things need to happen:
Look for coupon codes in a specific URL argument (?coupons=ABC123,DEF456) and save them to the user’s session.
Implement an order processor that can check for those codes and apply them to an order (if and when an order/cart exists for the session).
Step 1: Listen for the KernelEvents::REQUEST event
The KernelEvents::REQUEST event is dispatched by the Symfony HTTP kernel in the first part of the page request life cycle and allows subscribers to alter the request that is sent to Drupal. In our case, we want to check if the request contains a coupons parameter.
So we’ll create and register one basic event subscriber that looks for the query arg and saves it for later.
We’ll call it ‘my_module.url_coupon_subscriber’.
my_module.services.yml:
UrlCouponSubscriber.php:
If the parameter exists, we just want to save the coupon codes in the current user’s session. We don’t neccessarily want to load them when they are passed in. We may not ever have an order, so all we want to do is save the coupon codes for now. But knowing that later we will want to check if coupons exist, are valid, and to be able to apply them to an order, there’s a ::getUrlCoupons method.
Step 2: Implement an order processor to apply the coupons
By tagging a service ‘commerce_order.order_processor’, the Order module will allow our code to respond to the Order Refresh process and make changes to the order.
In this order processor, we’ll want to check for those coupon codes we saved in the event subscriber. So we inject our ‘my_module.url_coupon_subscriber’ service dependency in the arguments: [] section of the order processor’s service.
Also, it is important to notice that the priority is set to 60. This is to make sure this processor runs before the PromotionOrderProcessor that actually checks for related Promotions and applies them to the order.