Magento2 programmatically create coupon
Magento 2

Magento2 programmatically create coupon

In this article, i have explaining how to we can create coupon programmatically.

At Magento 2, if you wish to create a coupon programatically .

Follow below steps:

  • First, you have to create a Cart Price rule/Shopping Cart rule.
  • At, Second steps you will create coupon code.

Advanced sales promotion rules like #free-gift, discount on #first-order, #nth-order, #total-sales-amount, #total-order-number #specific-customers #subscribers etc.http://bit.ly/M2-Sales-Promotion


1.Create Cart Price rules

For a create rules, i have used repository interface classes:

Magento\SalesRule\Api\RuleRepositoryInterface
Magento\SalesRule\Api\CouponRepositoryInterface

For set the data for rules repository class, we have use the interface

Magento\SalesRule\Api\Data\RuleInterface

This interface some setter methods using this setter method, using those method you can set discount percent/amount ,rules starting & ending date ,conditions of a rules.

Here an example code of Create Cart price rule

<?php

namespace DevAmitbera\CustomModule\Model;

use Magento\SalesRule\Api\Data\RuleInterface;
use Magento\SalesRule\Api\RuleRepositoryInterface;
use Magento\SalesRule\Model\CouponFactory;
use Magento\SalesRule\Model\RuleFactory;


class Test 
{

    /**
     * @var RuleInterface
     */
    private $rule;

    /**
     * @var RuleFactory
     */
    private $ruleFactory;

    /**
     * @var RuleRepositoryInterface
     */
    private $RuleRepository;

    public function __construct(
            RuleRepositoryInterface $RuleRepository,
            RuleFactory $ruleFactory,
            RuleInterface $rule
    ) {
        $this->RuleRepository = $RuleRepository;
        $this->ruleFactory = $ruleFactory;
        $this->rule = $rule;
    }


    public function createCartRules() {

        $rule =$this->rule;
        $rule->setName('5% discount') // Rules name
                ->setDescription('5% discount on all')
                ->setIsAdvanced(true)
                ->setStopRulesProcessing(false)
                ->setDiscountQty(5)
                ->setCustomerGroupIds([0, 1])
                ->setWebsiteIds([1])
                ->setUseAutoGeneration(0)    // If want to auto generate
                ->setCouponType(RuleInterface::COUPON_TYPE_SPECIFIC_COUPON)
                ->setSimpleAction(RuleInterface::DISCOUNT_ACTION_FIXED_AMOUNT_FOR_CART)
                ->setUsesPerCoupon(100)
                ->setUsesPerCustomer(2)
                ->setDiscountAmount(10)
                ->setFromDate('2019-04-01') //Format YYYY-MM-DD
                ->setToDate('2039-04-14') //Format YYYY-MM-DD
                ->setIsActive(true);

        try {
            $resultRules = $this->RuleRepository->save($rule);
        } catch (\Magento\Framework\Exception\LocalizedException $ex) {
            var_dump($ex->getMessage());
        }
    }

}

Parameters of Setter methods

  • setName() Method used for set  Rule Name.
  • setDescription($description) used for set for rule Description
  • setIsActive() is used for Enabled disabled Rule.Its value is true or false
  • setCustomerGroupIds($customerGroupIds) Method used for  Customer Groups field value. Parameters type Shoule Array like [0, 1]. 
  • setWebsiteIds($websiteIds) used for set Websites field.$websiteIds Type means parameters type should be Array .LIke setWebsiteIds([1]).A single website ‘s website id is 1.
  • setCouponType($couponType), Using this method you can set Coupon type .$couponType Variable type integer and It value will be 1 (No Coupon) or 2 (Specific Coupon)
  • setUseAutoGeneration($useAutoGeneration) use for create auto generate coupon.Parameter type boolean means true or false   . 
  • setSimpleAction($simpleAction) it is use for set Coupon discount type means Value of  Apply field at Action tab.It value may be by_percent (i.e Percent of product price discount),by_fixed(i.e Fixed amount discount) oR cart_fixed(i.e Fixed amount discount for whole cart)Or buy_x_get_y(i.e Buy X get Y free (discount amount is Y))
  • setDiscountAmount($discountAmount) is use for set field Discount Amount value
  • setDiscountQty($discountQty) is use for set  Maximum Qty Discount is Applied To field value. It value will be an integer.
  • setSimpleFreeShipping($simpleFreeShipping) is use for set Free Shipping field .It value should be string and value will be 0 (I.e No),1 (I.e For matching items only),2 ( I.e For shipment with matching items)

See more details about the setter function interface Magento\SalesRule\Api\Data\RuleInterface


Create Coupon of the rule

After creating Cart Price rules, you may be want to the coupon code

Use below Class

Magento\SalesRule\Api\CouponRepositoryInterface:save

Data Provider interface : Magento\SalesRule\Api\Data\CouponInterface

/*
* $this->couponFactory \Magento\SalesRule\Model\CouponFactory
* @coupon \Magento\SalesRule\Api\Data\CouponInterface
*/
$coupon = $this->couponFactory->create();

$coupon->setCode($couponCode)
        ->setIsPrimary(true)
        ->setRuleId($rulesId());
$this->couponRepository->save($coupon);

Here note that setIsPrimary() parameters should be true /false means boolean

If you want to Coupon Code at Rule Information  Section

,then you have to make setIsPrimary(true) .

Code Sample for Create Single Coupon for a rule

<?php


namespace Stackexchange\Magento\Observer;

use Magento\SalesRule\Api\CouponRepositoryInterface;
use Magento\SalesRule\Api\Data\CouponInterface;
use Magento\SalesRule\Api\Data\RuleInterface;
use Magento\SalesRule\Api\RuleRepositoryInterface;
use Magento\SalesRule\Model\CouponFactory;
use Magento\SalesRule\Model\RuleFactory;
use Magento\Framework\Math\Random;
use Magento\SalesRule\Api\Data\CouponGenerationSpecInterfaceFactory;
use Magento\SalesRule\Model\Service\CouponManagementService;

class CreateCouponCustomer {

    /**
     * @var CouponGenerationSpecInterfaceFactory
     */
    private $generationSpecFactory;

    /**
     * @var CouponManagementService
     */
    private $couponManagementService;

    /**
     * @var Random
     */
    private $random;

    /**
     * @var CouponFactory
     */
    private $couponFactory;

    /**
     * @var RuleFactory
     */
    private $ruleFactory;

    /**
     * @var CouponRepositoryInterface
     */
    private $couponRepository;

    /**
     * @var RuleRepositoryInterface
     */
    private $RuleRepository;

    public function __construct(
      CouponRepositoryInterface $couponRepository,
      RuleRepositoryInterface $RuleRepository,
      CouponFactory $couponFactory,   
      RuleFactory $ruleFactory,
      Random $random,
     CouponGenerationSpecInterfaceFactory $generationSpecFactory,
     CouponManagementService $couponManagementService       
    ) {
        
        $this->RuleRepository = $RuleRepository;
        $this->couponRepository = $couponRepository;
        $this->ruleFactory = $ruleFactory;
        $this->couponFactory = $couponFactory;
        $this->random = $random;
        $this->couponManagementService = $couponManagementService;
        $this->generationSpecFactory = $generationSpecFactory;
    }
    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        $customer = $observer->getEvent()->getCustomer();
        $rule =  $this->ruleFactory->create();
        $rule->setName('5% discount')
            ->setIsAdvanced(true)
            ->setStopRulesProcessing(false)
            ->setDiscountQty(10)
            ->setCustomerGroupIds([$customer->getGroupId()])
            ->setWebsiteIds([1])
            ->setCouponType(RuleInterface::COUPON_TYPE_SPECIFIC_COUPON)
            ->setSimpleAction(RuleInterface::DISCOUNT_ACTION_FIXED_AMOUNT_FOR_CART)
            ->setDiscountAmount(10)
            ->setIsActive(true);
        
        try{
            $resultRules = $this->RuleRepository->save($rule);
            $this->createCouponCode($resultRules);
        } catch (\Magento\Framework\Exception\LocalizedException $ex) {

        }
        
    }
    private function createCouponCode(RuleInterface $rule)
    {
        $couponCode = $this->random->getRandomString(8);
        $coupon = $this->couponFactory->create();
        $coupon->setCode($couponCode)
                ->setIsPrimary(1)
                ->setRuleId($rule->getRuleId());
        $this->couponRepository->save($coupon);
    }
}

At the example, I have created a random coupon code by creating 8 lengths using Magento\Framework\Math\Random::getRandomString(8)


Create Auto generate multiple Coupon for a single rule

Want auto generate multiple Coupon codes, that you donot need to use below class

Magento\SalesRule\Api\CouponRepositoryInterface;
Magento\SalesRule\Api\Data\CouponInterface;

Used the classes:

  • Magento\SalesRule\Api\Data\CouponGenerationSpecInterfaceFactory;
  • Magento\SalesRule\Model\Service\CouponManagementService;

This is coupon does not show at Rule Information  

Auto generate Coupon

Section and it will show at Manage Coupon Codes section.

        $couponSpecData = [
            'rule_id' => $ruleId(),
            'qty' => 5, // How many coupon you want to create 
            'length' => 12, // Coupon length
            'format' => 'alphanum', // Alphanumeric = alphanum, Alphabetical = alpha ,
            'prefix' => 'A', // Can use Null 'prefix' =>  null,
            'suffix' => 'Z', // Can use Null 'prefix' =>  null,
            'dash' => 0, // Can use Null 'prefix' =>  null,
            'quantity' => 5 // How coupon you want to create 
        ];
        /**
         * @var $this->generationSpecFactory \Magento\SalesRule\Api\Data\CouponGenerationSpecInterfaceFactory
         * @var $this->couponManagementService \Magento\SalesRule\Model\Service\CouponManagementService
         */
        $couponSpec = $this->generationSpecFactory->create(['data' => $couponSpecData]);
        $this->couponManagementService->generate($couponSpec);

Here rule_id,Coupon Qty : qty,Code Length:length & quantity,Code Format: format are required fields

Simple Code for Auto generate coupon code

<?php

namespace StackExchange\Magento\Model;

use Magento\SalesRule\Api\CouponRepositoryInterface;
use Magento\SalesRule\Api\Data\CouponInterface;
use Magento\SalesRule\Api\Data\RuleInterface;
use Magento\SalesRule\Api\RuleRepositoryInterface;
use Magento\SalesRule\Model\CouponFactory;
use Magento\SalesRule\Model\RuleFactory;
use Magento\Framework\Math\Random;
use Magento\SalesRule\Api\Data\CouponGenerationSpecInterfaceFactory;
use Magento\SalesRule\Model\Service\CouponManagementService;

class AutoCoupon {

    /**
     * @var RuleInterface
     */
    private $rule;

    /**
     * @var CouponGenerationSpecInterfaceFactory
     */
    private $generationSpecFactory;

    /**
     * @var CouponManagementService
     */
    private $couponManagementService;

    /**
     * @var Random
     */
    private $random;

    /**
     * @var CouponFactory
     */
    private $couponFactory;

    /**
     * @var RuleFactory
     */
    private $ruleFactory;

    /**
     * @var CouponRepositoryInterface
     */
    private $couponRepository;

    /**
     * @var RuleRepositoryInterface
     */
    private $RuleRepository;

    public function __construct(
            CouponRepositoryInterface $couponRepository,
            RuleRepositoryInterface $RuleRepository,
            CouponFactory $couponFactory,
            RuleFactory $ruleFactory,
            RuleInterface $rule,
            Random $random,
            CouponGenerationSpecInterfaceFactory $generationSpecFactory,
            CouponManagementService $couponManagementService
    ) {
        $this->RuleRepository = $RuleRepository;
        $this->couponRepository = $couponRepository;
        $this->ruleFactory = $ruleFactory;
        $this->couponFactory = $couponFactory;
        $this->random = $random;
        $this->couponManagementService = $couponManagementService;
        $this->generationSpecFactory = $generationSpecFactory;
        $this->rule = $rule;
    }


    public function createCartRules() {

        $rule =$this->rule;
        $rule->setName('5% discount') // Rules name
                ->setDescription('5% discount on all')
                ->setIsAdvanced(true)
                ->setStopRulesProcessing(false)
                ->setDiscountQty(5)
                ->setCustomerGroupIds([0, 1])
                ->setWebsiteIds([1])
                ->setUseAutoGeneration(true)    // If want to auto generate
                ->setCouponType(RuleInterface::COUPON_TYPE_SPECIFIC_COUPON)
                ->setSimpleAction(RuleInterface::DISCOUNT_ACTION_FIXED_AMOUNT_FOR_CART)
                ->setUsesPerCoupon(100)
                ->setUsesPerCustomer(2)
             
                ->setDiscountAmount(10)
                ->setFromDate('2019-04-01') //Format YYYY-MM-DD
                ->setToDate('2039-04-14') //Format YYYY-MM-DD
                ->setIsActive(true);

        try {
            $resultRules = $this->RuleRepository->save($rule);
            $this->autoGenerateCouponOnSingleRules($resultRules);
        } catch (\Magento\Framework\Exception\LocalizedException $ex) {
            var_dump($ex->getMessage());
        }
    }
    /**
     * 
     * @param RuleInterface $rule
     */
    private function autoGenerateCouponOnSingleRules(RuleInterface $rule)
    {
        $couponSpecData = [
            'rule_id' => $rule->getRuleId(),
            'qty' => 5, // How coupon you want to create 
            'length' => 12, // Coupon length
            'format' => 'alphanum', // Alphanumeric = alphanum, Alphabetical = alpha ,
            'prefix' => 'A', // Can use Null 'prefix' =>  null,
            'suffix' => 'Z', // Can use Null 'prefix' =>  null,
            'dash' => 0, // Can use Null 'prefix' =>  null,
            'quantity' => 5 // How coupon you want to create 
        ];
        
        $couponSpec = $this->generationSpecFactory->create(['data' => $couponSpecData]);
        $this->couponManagementService->generate($couponSpec);
    }  
}

More Article