Click here to Skip to main content
15,901,373 members
Articles / Web Development / ASP.NET

Credit Card Fraud detection using minFraud

Rate me:
Please Sign up or sign in to vote.
3.00/5 (14 votes)
7 Jun 2006CPOL2 min read 75.6K   1.3K   19   19
C#/ASP.NET implementation of minFraud credit card fraud detection

Sample Image - MinFraudExample.png

Introduction

Any business that accepts credit cards online will quickly learn that standard credit card checks are insufficient. An additional layer you can add is IP location and email validation.

In this article I will set out to explain how to implement the minFraud service from MaxMind using ASP.NET and C#.

Using the code

The minFraud interface implementation shown here has 2 parts:

  1. Collection of credit card information.
  2. The class that contacts minFraud for a fraud score.

Collect User Information

The first part is just a web page, WebForm1.aspx. It collects the credit card information and calls the minFraud class to get the fraud score and results. You should use the country code (e.g. US, CA etc.) for the country and the zipcode can be a postal code. The format for phone numbers is very tolerant and need not conform to any particular style. CC Bin is the first 6 digits of a credit card. For security reasons do not send the full credit card number to minFraud.

Clicking "check" will send the results to minFraud for scoring.

private void btnCheck_Click(object sender, System.EventArgs e)
{
    CCInfo ccInfo = new CCInfo();
    ccInfo.IP = txtIP.Text;
    ccInfo.City = txtCity.Text;
    ccInfo.State = txtState.Text;
    ccInfo.ZipCode = txtZip.Text;
    ccInfo.Country = txtCountry.Text;
    ccInfo.EMail = txtEmail.Text;
    ccInfo.Phone = txtPhone.Text;
    ccInfo.Bin = txtBin.Text;

    double fraudScore;
    string info;
    if (MinFraud.IsSafe(ccInfo, out fraudScore, out info))
    {
        lblSafe.ForeColor = Color.Green;
        lblSafe.Text = "Yes";
    }
    else
    {
        lblSafe.ForeColor = Color.Red;
        lblSafe.Text = "No";
    }

    lblScore.Text = fraudScore.ToString();
    lblResults.Text = info;
}

Score User Information

The second part is a class to post the user information to the minFraud website. All the information on contacting and parsing results is contained in the class MinFraud. Be sure to change _minFraudKey to your own key. I chose to use the SSL link to minFraud servers in this example. They also provide a non SSL link. Because minFraud uses a scoring system you can easily adjust your risk by adjusting _fraudLimit to a level you are comfortable with. It is recommended that in a production system you move this variable to your web.config until you find the correct level.

public static bool IsSafe(CCInfo ccInfo, out double fraudScore, out string info)
{
    bool safe = false;
    fraudScore = 10.0;
    info = string.Empty;

    HttpWebResponse webResponse = null;

    try
    {
        // Write the request to gateway (required data)
        string reqString = "i=" + ccInfo.IP;
        reqString += "&city=" + HttpUtility.UrlEncode(ccInfo.City);
        reqString += "&region=" + HttpUtility.UrlEncode(ccInfo.State);
        reqString += "&postal=" + HttpUtility.UrlEncode(ccInfo.ZipCode);
        reqString += "&country=" + HttpUtility.UrlEncode(ccInfo.Country);
        reqString += "&license_key=" + _minFraudKey;

        // optional data
        if (ccInfo.Phone.Length > 0)
        {
            reqString += "&custPhone=" + ccInfo.Phone;
        }
        if (ccInfo.Bin.Length > 0)
        {
            reqString += "&bin=" + ccInfo.Bin;
        }

        // Calc MD5 on email
        if (ccInfo.EMail.Length > 0)
        {
            string emailDomain = ccInfo.EMail.Substring(ccInfo.EMail.IndexOf("@") + 1);
            reqString += "&domain=" + emailDomain;
            reqString += "&emailMD5=" + EmailHash(ccInfo.EMail);
        }

        // Find content length
        UTF8Encoding encoding = new UTF8Encoding();
        Byte[] byteArray = encoding.GetBytes(reqString);

        // Create the request back
        HttpWebRequest req = (HttpWebRequest)WebRequest.Create(_minFraudAddress);

        try
        {
            // Set values for the request back
            req.ContentLength = byteArray.Length;
            req.Method = "POST";
            req.ContentType = "application/x-www-form-urlencoded";
            req.Timeout = 5000;

            using (Stream requestStream = req.GetRequestStream())
            {
                requestStream.Write(byteArray, 0, byteArray.Length);
                requestStream.Close();
            }

            // Do the request to Gateway and get the response
            webResponse = (HttpWebResponse)req.GetResponse();
        }
        catch
        {
            if (null != webResponse)
            {
                webResponse.Close();
            }

            // Attempt to use secondary server
            req = (HttpWebRequest)WebRequest.Create(_minFraudAddress2);

            // Set values for the request back
            req.ContentLength = byteArray.Length;
            req.Method = "POST";
            req.ContentType = "application/x-www-form-urlencoded";
            req.Timeout = 5000;

            using (Stream requestStream = req.GetRequestStream())
            {
                requestStream.Write(byteArray, 0, byteArray.Length);
                requestStream.Close();
            }
            webResponse = (HttpWebResponse)req.GetResponse();
        }

        Stream strm = webResponse.GetResponseStream();
        StreamReader stIn = new StreamReader(strm);
        info = stIn.ReadToEnd();
        stIn.Close();

        // Check response for errors and such
        char[] splitChars = { ';' };
        string[] respCodes = info.Split(splitChars);

        foreach (string s in respCodes)
        {
            if (-1 != s.IndexOf("score="))
            {
                fraudScore = double.Parse(HttpUtility.UrlDecode(s.Substring(s.IndexOf("=") + 1)));

                safe = (fraudScore < _fraudLimit);
                break; // nothing else to do for now
            }
        }
    }
    catch
    {
        // Log exception
    }
    finally
    {
        if (null != webResponse)
        {
            webResponse.Close();
        }
    }

    return safe;
}

An interesting feature of minFraud is that it contains a live database of suspected fraudulent email addresses. You can check your customers email address against this database by doing an MD5 hash on the email address and passing it to minFraud.

private static string EmailHash(string email)
{
    // Must be lower case before hashing
    email = email.ToLower();

    Encoder enc = System.Text.Encoding.UTF8.GetEncoder();

    // Create a buffer large enough to hold the string
    byte[] byteText = new byte[email.Length];
    enc.GetBytes(email.ToCharArray(), 0, email.Length, byteText, 0, true);

    // Now that we have a byte array we can ask the CSP to hash it
    MD5 md5 = new MD5CryptoServiceProvider();
    byte[] result = md5.ComputeHash(byteText);

    // Build the final string by converting each byte
    // into hex and appending it to a StringBuilder
    StringBuilder downloadHash = new StringBuilder();
    foreach (byte b in result)
    {
        downloadHash.Append(Convert.ToString(b, 16).PadLeft(2, '0'));
    }

    return downloadHash.ToString();
}

More Information

To setup a free trial account for minFraud visit www.maxmind.com

Disclaimer

This documentation and the accompanying files are provided "as is" with no expressed or implied warranty. No responsibilities for possible damages, or side effects in its functionality. The user must assume the entire risk of using this code. The author and Screaming Bee LLC accepts no liability if it causes any damage to your computer, website, software, reputation or your love life. Use at your own risk.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer
United States United States
Shawn is President and co-founder of Screaming Bee LLC.

He has been developing software for more years then he cares to remember. One of his ealiest projects, AutoGreet, written in 6502 assembly won him the affection and hatred of a multiline BBS community (remember those?).

Currently his projects involve ASP.NET/C# and driver development at Screaming Bee.

Screaming Bee is a leader in voice changing software and solutions for online games and messenger applications.

For more information please visit: http://www.screamingbee.com

Comments and Discussions

 
GeneralYour Approach is Terrible and Violates VISA Regulations Pin
Bill SerGio, The Infomercial King4-Oct-08 4:16
Bill SerGio, The Infomercial King4-Oct-08 4:16 
GeneralWow such venom Pin
Shawn Pourchot7-Jun-06 8:09
Shawn Pourchot7-Jun-06 8:09 
When I put this article together I never imagined it would be controversial. Perhaps you folks should save your venom for MaxMind they are the ones actually selling the service. I merely wrote a wrapper to use their service.

I'm a little confused about why people are so upset. This is merely another indicator of suspected fraud and is based on a scoring system that the merchant can adjust to the level they think is appropriate. Unlike face to face credit cards it is very hard to verify that the person actually possesses the card, and with the recent thefts the current system of CVV2 and AVS are a joke as far as preventing fraud.

By accepting fraudulent transactions merchants can be fined, loose the ability to take cards and loose money on their merchandise so like all things it's a trade-off, how much fraud do you tolerate versus how many customers do you turn away.

As to alternatives if such a system declines a card: Well there is always PayPal, GoldMoney, E-Gold and a number of other systems that handle transactions without credit cards. Merchants can also queue up the suspect transaction to do a manual verification before delivering the product. MaxMind offers another service that uses the phone system for verification of transactions, this might help merchants whose customers are frequent travelers.

I'm not saying any of these things are perfect but the more tools a merchant has the better off they are going to be when it comes to fraud prevention.

Shawn Pourchot
Screaming Bee LLC
www.screamingbee.com
"Changing the way people play games and chat online."
GeneralYou wasted our time Pin
Bill SerGio, The Infomercial King8-Jun-06 11:13
Bill SerGio, The Infomercial King8-Jun-06 11:13 
GeneralRe: You wasted our time Pin
Ryan Binns15-Jun-06 21:31
Ryan Binns15-Jun-06 21:31 
GeneralTotally Flawed Pin
Varindir Rajesh Mahdihar7-Jun-06 7:40
Varindir Rajesh Mahdihar7-Jun-06 7:40 
GeneralYour article STINKS! Pin
Bill SerGio, The Infomercial King7-Jun-06 7:12
Bill SerGio, The Infomercial King7-Jun-06 7:12 
GeneralRe: Your article STINKS! Pin
zacharycat7-Jun-06 7:36
zacharycat7-Jun-06 7:36 
GeneralRe: Your article STINKS! Pin
Bill SerGio, The Infomercial King8-Jun-06 11:14
Bill SerGio, The Infomercial King8-Jun-06 11:14 
GeneralRe: Your article STINKS! Pin
zacharycat8-Jun-06 11:38
zacharycat8-Jun-06 11:38 
GeneralRe: Your article STINKS! Pin
Bill SerGio, The Infomercial King8-Jun-06 12:34
Bill SerGio, The Infomercial King8-Jun-06 12:34 
GeneralRe: Your article STINKS! Pin
_Zorro_7-Jun-06 8:29
professional_Zorro_7-Jun-06 8:29 
GeneralRe: Your article STINKS! Pin
Bill SerGio, The Infomercial King8-Jun-06 11:16
Bill SerGio, The Infomercial King8-Jun-06 11:16 
GeneralRe: Your article STINKS! Pin
kaschimer7-Jun-06 8:45
kaschimer7-Jun-06 8:45 
GeneralRe: Your article STINKS! Pin
Bill SerGio, The Infomercial King8-Jun-06 11:18
Bill SerGio, The Infomercial King8-Jun-06 11:18 
GeneralRe: Your article STINKS! Pin
ss__m4-Jul-06 5:03
ss__m4-Jul-06 5:03 
GeneralRe: Your article STINKS! Pin
MrGoodly9-Feb-07 20:16
MrGoodly9-Feb-07 20:16 
GeneralHmmm - Mapping IP address to address! Pin
Nish Nishant7-Jun-06 6:45
sitebuilderNish Nishant7-Jun-06 6:45 
GeneralRe: Hmmm - Mapping IP address to address! Pin
Shawn Pourchot7-Jun-06 7:11
Shawn Pourchot7-Jun-06 7:11 
GeneralRe: Hmmm - Mapping IP address to address! Pin
Nish Nishant7-Jun-06 7:25
sitebuilderNish Nishant7-Jun-06 7:25 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.