Want to generate numeric coupon codes? We want to generate coupon code series and then encrypt those coupon code in numeric only, and that must also be decipherable. 

We will be sharing encrypted code as coupon code with customer.

These are the conditions:


Encrypted code must not be in series or not easily able to guess;
Encrypted code must be numeric.
Encrypted code must be having a specific number of digits (think: size/length).


Example :

We generate coupon code from 1 to 100 (needs in millions and plainCode will be either numeric or alphanumeric doesn't matter).

We want share encrypted numeric coupon code with specific digits to user. 
i.e. if code is 52 then encrypted code gives us between 10000 to 99999 (if 5 digits are specified or it need to be fix number of digits)

We are also able to decrypt the same.

Note: 


Above is just an example. possibilities are in millions.
Security is not a major concern. just not able to guess is matters a lot.
encrypted code must be in numeric.


Question:

Is there an established, cryptographical secure way to do this? If not, what would we need to do to handle this?

Any suggestions or ideas are more than welcome.

We have looked and FPE. Any good algo for the same recommended which return in specific number of digits. We have one which gives encrypted numbers less than specified number but we want in between specific range to maintain number of digits without 0 appending.
I have an almost identical requirement for location identifiers I use in a custom inventory system. I have a 35-bit code, which is displayed as 7 5-bit elements, which need to be human readable and unique. The method to generate the codes does not necessarily have to be format preserving, that can just be a side effect of the algorithm used.

The method I use generates a 7 character code, with each character being alphanumeric 0-9 and A-Z, omitting OIZS because they are too similar visually to 0125. Internally the algorithm is a block cipher called Bromine with 5 7-bit elements in a generalized Feistel network, which is based on the round structure of the HIGHT block cipher. The input is a numerical sequence, and the output is a pseudorandom alphanumeric sequence:

JE4HV9W
JPNJ4NE
V20MUP3
QCKCVWU
QTR7FUC
5E94W9J
4HYWH14
9W1229T
PT6JJTV
MEWTT68
91ACL19
....


Because the input sequence is numeric, there are only 10 million output combinations for the given 34.36 billion possibilities for a 35-bit value. This limits the number of ciphertexts available to reverse engineer the algorithm or determine the key used. The algorithm is simple but has enough rounds to be secure given the key size (in theory). The use environment has no requirement for this kind of security, but it allows it to be used for other applications if needed. The numeric input is a security and usability requirement, and not a limitation of the algorithm.

If used to generate coupon codes, certain input elements or bits can be fixed, and those fixed bits can define the coupon type or discount. The system would only need to keep track of used coupon codes, and decode them to determine the type and validity. Only 1/3436 codes entered randomly will decode to a valid input, and the number of coupons from valid inputs can also be limited further.

For example, your input could be structured as XXYYYYZ, where XX is the coupon type, YYYY is the value, and Z is a fixed element such as 0. Coupon 01 would be assigned to a 5% discount with only 100 allowed coupon uses before it expires. When entered into the system, it is decoded, its structural validity is determined (is numeric and Z=0), XX is determined to be a valid coupon, and YYYY is determined to have not been yet used for a given XX. If all requirements are met, the discount is given, and XXYYYY is saved for comparison with further coupons. Only 0.003% of this example format meets the required structure and only 1% of these decode to the desired coupon type.

If a longer code is required, variants of such a cipher are easily generated in other sizes. The 40-bit version extends the subwords to 8-bits, and is displayed as an 8 character code. A 42-bit version for display as 6-bit 7 character codes is created by extending the 5 subword 7-bit Feistel structure to 6 subwords, and the 48-bit version extends its subwords to 8-bits.