Serialized coupons allow merchandisers to create large numbers of coupons with usage limits and randomly generated coupon codes in order to closely target and monitor coupon use.
The merchandiser creates a CouponBatch
repository item that stores all of the information for the batch of serialized coupons, and uses the batch to generate the desired number of coupon codes. The merchandiser supplies a prefix for the entire batch, and the remainder of the code is randomly generated, as shown in the following examples.
Coupon Code | Prefix | Coupon Number | Validation Characters |
---|---|---|---|
HOL1HV5432 | HOL | 1HV5 | 432 |
SHIP6LKC4GC | SHIP | 6LKC | 4GC |
CouponBatch Repository Item
The CouponBatch
item descriptor holds all of the information related to generating and validating a set of serialized coupon codes, including the promotions to use for the coupon. The CouponBatch
item descriptor implements the following properties, which are used to generate and validate coupon codes:
Property | Definition | Datatype | Required |
---|---|---|---|
| String of characters that appears at the start of every coupon code generated by the BatchCoupon. | String | Y |
| Indicates how many coupon codes to generate for a batch. | Int | Y |
| A binary array that is used to create a static seed for creating the coupon codes. This value is set when a BatchCoupon is created, and stored to allow the codes to be validated or regenerated. | Binary | N |
percentClaimed | The percentage of coupon batches that have been claimed. This derivation queries for all | Float | N/A |
numberClaimed | The number of coupons that have been claimed at least once. | Int | N/A |
Two related repository items are the BatchPromotionClaimable
and the PromotionClaimable
item. A BatchPromotionClaimable
claimable item type is created when a coupon is claimed from a coupon batch. The item descriptor extends the PromotionClaimable
item descriptor and adds an additional couponBatch
property. The couponBatch
property is a reference to the CouponBatch
that created the BatchPromotionClaimable
.
The uses
and maxUses
properties of the PromotionClaimable
item descriptor are used to set usage limits for any PromotionClaimable
item. The maxUses
property is configurable; the uses
property increments when a customer tries to claim a coupon. If uses
is greater than maxUses
, the coupon has no more remaining uses and cannot be claimed anymore. If maxUses
is -1, then the coupon can be claimed an unlimited number of times.
How Batch Coupon Codes Are Generated
In order to generate coupon codes for a coupon batch, the generateCouponBatchCodes
method in the CouponBatchTools
class checks to see if the seedValue
is populated for the batch. The seedValue
is typically set when the CouponBatch
item is created; if it has not been set, a new random array of bytes is generated (via SecureRandomService
) and saved as the batch’s seedValue
. This seedValue
is used to ensure that each CouponBatch
has a different set of validation codes; storing it ensures that the codes can be regenerated or validated at a later time.
The generateCouponBatchCodes()
method uses the seedValue
as a seed to a random number generator to obtain an array of random bytes, which are then parsed into an encoded base-32 number. The length of the encoded character segment is determined by the couponBatchTools
component’s couponBatchNumberLength
property. The encoded characters form the coupon number, which is the first portion of the coupon code. This process ensures that the coupon numbers are non-sequential. Duplicates are discarded.
Next, the generateCouponBatchValidationSeed()
method generates a second seed specific to the coupon number. The new seed value is used to generate an additional array of bytes encoded in base-32, which is used as the validation characters. The number of characters in the resulting code depends on the CouponBatchTools
component’s configured couponBatchValidationLength
value.
The complete coupon code consists of the prefix + coupon number + verification code, and is stored in the generateCouponBatchCodes()
method’s HashMap.
Note that you can adjust the length of the coupon code (which is supplied by the merchandiser when the coupon batch is created), and that this affects the length of the other sections, the number of coupons that can be generated, and the odds of a user guessing a code. The number of coupons that can be generated for a batch is 32^n, where n is the number of characters used in the coupon number. In practice, the number of coupons generated per batch will be less than the maximum.
A user has a 1/(32^n) chance of brute force guessing the validation characters correctly, where n is the length of the validation code. For example if there are 3 validation characters then the user has a 1/32,786 chance of guessing the proper set of validation characters for a given code if they use a proper prefix and correct coupon code length.
How Serialized Coupons Are Claimed
Just as it does for ordinary coupons, the ClaimableManager
handles the claiming process for coupon codes from a BatchCoupon
. If a coupon item is not found for the given code, the ClaimableManager
checks the CouponBatch
item descriptors to see if any batches match the coupon prefix. If a match is found, the remaining parts of the coupon code are decoded and validated. If the coupon code is valid, the coupon is active, no claimable item yet exists for the coupon (for coupons that can be used multiple times), and the coupon is valid for the current site, then a BatchPromotionClaimable
item is created and granted to the user.
Note that if the coupon can be used multiple times, the claimable item is created on the first use; on subsequent uses, the existing coupon is found and no item is created.
The BatchPromotionClaimable
uses the passed coupon code, including the prefix, as the ID. The startDate
, endDate
, promotions
, and displayName
properties are copied over from the CouponBatch
to the new BatchPromotionClaimable
item. The BatchPromotionClaimable
item’s uses
property is set to the CouponBatch
item’s uses value minus 1 (the first claim is also counted),, and the couponBatch
property on the claimable item is set to the CouponBatch
ID.
The claimCoupon()
method checks the uses property to determine if the coupon can still be claimed If the uses property equals 0 then an exception is thrown. Otherwise the coupon is claimed and if uses does not equal -1 the uses property is decremented.
CouponBatchTools
The CouponBatchTools
class handles the lower-level logic in manipulating CouponBatch
objects, such as generating the different parts of the coupon codes.
You can configure the following properties to change the characters allowed in coupon codes and how many coupons can be generated for a single batch:
Property Name | Type | Default Value | Description |
---|---|---|---|
| int | 4 | Determines the number of characters used as a unique identifier for the coupon number. |
| int | 3 | Determines the number of characters used as validation for the passed in coupon code. |
| array | Character set of 0-9, &, *, A-Z excluding A,E, I, L, O and U | The set of characters that will appear in generated coupon codes. Must contain exactly 32 unique values. Default characters are 0-9, and A-Z excluding a, e, i, o, and u. |
| double | 0.96 | Restricts the number of coupons that can be generated for a batch to a ratio of the total possible unique codes that can be generated for a batch. 0.96 was chosen as a default because it allows for slightly more than 1 million coupons given the default |
The following additional properties refer to other components and configure the random number generator used by the CouponBatchTools
.
Property Name | Default Value | Purpose |
---|---|---|
|
| Component used to generate random numbers |
|
| Contains configuration information for using SecureRandom |
|
| Used to begin and end the transactions necessary for obtaining the # of claimed coupons or finding a coupon batch based on prefix. |