You can read coupon function Part 1 here.

Enable coupon functionality in Commerce Server runtime

Commerce Server uses pipeline infrastructure to orgnize runtime components. Feature pack 1 delivers three new components for coupon functionalities. To enable coupon in runtime, you need to do following modifications:

  • modify basket pipeline (or whatever pipeline in your site having the similar function), add ReservePromoCodes component, make sure to place it before OrderDiscount and OrderLevelDiscountApply components. Add RecordPromoCodes component and place it after OrderDiscount and OrderLevelDiscountApply
  • modify checkout pipeline (or whatever pipeline in your site having the similar function), add RedeemPromoCodes component.
  • change site discount cache configuration to load discount data from Marketing database. Remember, the coupon data, as part of new things introduced by FP1, only reside in marketing database. So unless you change the discount cache loader to load from new marketing database, the coupon function won't work. To do that, you need to update web.config, <caches> section, change discounts cache type to “MarketingDiscounts” 

Of course, it is necessary to make some changes in your site codes as well (basically to get the shoppers input of coupon codes and add those values to OrderForm). For a detailed sample, you can refer to up-to-date commerce server documentation shipped with FP1, inside Developer's Guide -> Developer Concepts and Tasks -> Marketing System -> Promotion Codes -> Implementing Promotion Codes 


Coupon reservation

When a shopper uses a coupon, under the hook, the coupon code goes through an input -> validated (and discount applied) -> Redeemed (when basket is checked out) process. However, when the coupon code's available usage limit is under a certain threshold, the validated coupon will be reserved and the coupon will get into a reserved status before the redemption.

What is available usage limit? In part 1 I discussed the usage limit for coupon code.  Actually, in the marketing system, we definition another two counters in addtion to usage limit. One is coupon's usedcount. It starts from zero. Whenever a coupon is redeemed during checkout, the usedcount will increase by one. The other counter is reserve count. It starts from zero also and only when a coupon gets into reserved mode, the reserved count increases by one. The available usage limit = usage limit - (usedcount + reserve count). And under no circumstance, the available usage limit should be below zero. Otherwise, the coupon will be overused. 

When available usage limit is under a configured threshold -- the threshold is defined as one property in marketing resource. Open commerce server manager, expand marketing resource and you can find a property for “Promocode reservation threshold“ and the default value is 100. So for a specific coupon code, when there are less than 100 (or whatever threshold value you set) times it can be used, each specific shopper input will get a reservation.  This will prevent concurrency scenario which will overuse the coupon (imagine 101 users come in, all input the valid public coupon and all the inputs get validated and redeemed -- the usedcount will be bigger than the usage limt).

Oh, one last thing about the counters (you probably already figured it out): when a coupon code is changed from reserved mode to redeemed mode, the counters are changed: reserved count decreases by one (it is not reserved any longer) and usedcount increases by one (it is redeemed).


Cancel expired coupon reservation task

Let's say, a coupon is entering reservation mode (available usage limit < threshold). Now a shopper inputs the coupon and gets a reservation. This will actually takes away a future usage of this coupon. So we have to, after a certian condition, release this reservation. For example, shopper enters the coupon but doesn't check out and he/she leaves lthe shopping cart for there forever -- the commerce server 2002 FP1 provides you a way to cancel the coupon reservation, if it has been idled over a specific period of time.

Like the reservation threshold introduced above, the reservation expiration time is also part of marketing resource. Expand the marketing resource, you can find a property named “Promocode reservation expiration time“. The default vaue is 30 minutes.

The tool to release reservation is a program called ExpirePromoCodeReservation.exe, under <commerce_server_root_directory>\FP1\. The best practice is to configure a windows scheduled task to run this program to automate the process. Details about how to configure is in Commerce Server FP1 documentation, under “Administering your site“ topic.

One last thing about this ExpirePromoCodeReservation.exe program. It accesses marketing database to cancel the reservation. So from security standpoint, it is good practice to grant only the minimal required permission to the identity running this program. That is, the mktg_promoCodeExpirationTask_role, which is pre-defined in marketing database.


Retrieve coupon information from OrderForm

In a previous blog post,  I talked about how to retrieve the useful information about discount applied record. Same approach can be used to parse OrderForm and get coupon status.

  • OrderForm.promo_codes

             A SimpleList of string, this is intended to keep the input coupon codes (site code should set this SimpleList)

  • OrderForm.promo_user_identity

            A string other than OrderForm.user_id to validate user identification for restricted coupon (which is introduced in part 1)

  • OrderForm.promo_code_info

            This is the majority information of coupons after running the basket pipeline. It is a SimpleList and each element is a Dictionary, containing information about each coupon. They are:

         name                                 type                  description

     promo_code                         string                 the coupon code

     promo_code_defintion_id     int                     promo code definition ID

     dt_promo_code_lookup       datetime            The timestamp when coupon was validated and/or reserved

     promo_code_reserved         bool                  whether the coupon is reserved or not

     promo_applied                    bool                  only when coupon is redeemed, it is true

     promo_code_status              int                     0 = OK (valid and/or reserved if reservation starts)

                                                                          1 = Invalid coupon code

                                                                          2 = coupon code's usage limit is reached

                                                                          3 = coupon is valid but related discount is expired

                                                                          4 = for restricted coupon, identity mismatch

  • (item)._itemlevel_discounts_applied and (item)._orderlevel_discount_applied.

         I introduced those two SimpleLists in previous blog about discount applied records. Now, with the coupon components, we add two more keys to each element (which is a Dictionary) in the SimpleLists. They are:

      name                            type        description

      promocode_defn_id     int           if using coupon makes the discount applied, this is the coupon definition ID

      promo_code               string        if using coupon makes the discount applied, this is the coupon code