0
votes

I have an application collecting credit card data. Before sending the information out to the payment entity I am trying to make sure the information entered is, at least, valid. I already worked out the card number and cvv numbers but I am not so sure about the expiry date. The format I get the info is MMYY. So what I am doing is:

-- Simple function to get current date and times
function getdatetime(tz)
    local tz = tz or 'America/New_York';
    local luatz  = require 'luatz';

    local function ts2tt(ts)
        return luatz.timetable.new_from_timestamp(ts);
    end

    local utcnow = luatz.time();
    local time_zone = luatz.get_tz(tz);
    local datetime_raw = tostring(ts2tt(time_zone:localise(utcnow)));
    local year, month, day, hour, min, sec, time_reminder = string.match(datetime_raw, "^(%d%d%d%d)%-(%d%d)%-(%d%d)[Tt](%d%d%.?%d*):(%d%d):(%d%d)()");

    return year, month, day, hour, min, sec;

end


local current_year, current_month = getdatetime()  -- Get current year/Month
local card_expiry_date = 'YYMM';     -- In the app this actually get a value eg: 2204, 2301, 2010, etc.

local card_exp_year = string.sub(card_expiry_date , 3, 4)
local card_exp_month = string.sub(card_expiry_date , 1, 2)

-- Extract the last two digits of the Year 
current_year = string.sub(current_year , 3, 4)

-- Check month is valid
if(card_exp_month < '01' or card_exp_month > '12')then 
   print("This is not a valid month")
else
   -- Check date is this month or after
   if((card_exp_year  < current_year) or (card_exp_year == current_year and card_exp_month < current_month))then
     print("Date cannot be before this month.")
   else
     print("All is good.")
   end
end

I do not know if this is the most elegant solution but it works. However it has a huge bug: it will fail at the end of the century. Since I only know the last two digits of the expiry date year, if a card expires in 2102 for instance and we were in 2099 my logic would wrongly reject the date (02 is less than 99).

I am very aware that me an my simple app will likely not be around by then but it bugs me to leave it like this.

Can anyone please suggest a proper way to do this validation?

Thank you!

Wilmar

1

1 Answers

0
votes

Credit cards usually expire within a few years. 3 years is average according to some quick web search. Also the owner of a century only card can be safely assumed to be dead and so is his card account.

So when you get a card with 02 in 2099 there is only one reasonable option.

Calculate two differences and pick the smaller one.

Something like local expiresIn = math.min(math.abs(99-2), math.abs(99-102))