Bin Service

 

Purpose:

This service accepts card data and returns information about the account including issuer and what it's capable of.

Integration: 

CardData GetCardDataFromPAN(string cardNumber, string expirationDate);

CardData GetCardDataFromBIN(string binNumber, int cardLength, string expirationDate);

In either case the input data is validated for:

  1. Card length (8 to 20)
  2. Card data is digits only
  3. Mod10 (skipped for Bin only)
  4. Expiration

CardData is defined as follows:

public class CardData
{
    public String Message { get;"set; }
    public ResultCode Result { get; set; }
    public Capability Capabilities { get; set; }
    public String Issuer { get; set; }
    public List<DebitNetwork> DebitNetworks { get; set; }
}

ResultCode is an enumeration as defined below:

public enum ResultCode
{
    Found,      // Card is valid and BIN information is included.
    BinNotFound,// Card appears valid, but no BIN information could be found.
    BadCard,    // Card is invalid, see message.
    Error       // System error occured, see message.

Capabilities is a Flag Enumeration as defined below:

[Flags]

public enum Capability
{
    Credit = 1,
    Debit = 2,
    Gift = 4, // Not yet supported
    Fleet = 8, // Not yet supported 
    FSA = 16, // Not yet supported 
    LVL2 = 32
}

Data Format:

There are currently 3 formats of bin data supported, they are described below. When BS reading through the bin files it will use the file name to determine what format to use while attempting the read. Files who's name can't be parsed into an appropriate format are ignored. The file name must consist of a card type followed by a format type (.XXX), this check is not case sensitive, the file extension is ignored. The basic credit card format would be CreditBasic.xml.

Valid card types are listed here.

Credit
Debit
FSA   // not currently implemented
Gift   // not currently implemented
Fleet   // not currently implemented

Valid format types are listed here.

basic   // this is the default for a given type
nab	    // this is the format we get from NAB 

Important Note: If an error occurs while parsing the Bin Tables out of the files, the service will NOT start. An error will be logged as appropriate.

CreditXML (CreditBasic.xml):

Use of this format to define the basic issuer ranges as well as commercial cards. This format MAY be expanded to support fleet, fsa, and gift.  When using this format the xsd file must also be present to allow for validation of the xml and data.  The xsd file must be named "CreditBasicDefinition.xsd".  

Simple Example

<BinTable xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="CreditBasicDefinition.xsd">
	<BinRange type="Visa">
		<validLength>13</validLength>
		<validLength>16</validLength>
		<range>
			<start>400000</start>
			<stop>499999</stop>
		</range>
		<commercialCard>
			<start>400127</start>
			<stop>400127</stop>
		</commercialCard>
	</BinRange>
</BinTable>

 Multiple lengths, ranges, and commercial cards are valid.  

NAB format (CreditNAB.csv)

This format is provided by NAB and is a combined format of 3 different formats for 3 different issuers.  It's capable of identifying Credit, Debit and Commercial card.  Attached to this Page you will find a PDF describing this format.  

This format replaces the GlobalDebit format previously in use.  

VCN,20131018,400002000   ,400002999   ,400002,C, ,US ,A , , ,  ,    ,1,16
VCO,20131018,400006000   ,400006999   ,400006,D, ,US ,G , , ,  ,    ,1,16
VDB,20131018,400006000   ,400006999   ,400006,D, ,US,G , , ,
MDB,5170140000000000000,5170149999999999999,00000001303,MDS,DMC,1,MDU,DNK
MCN,5170150000000000000,5170159999999999999,00000001303,MDG,DMC,1,MDG,DNK
MCO,5529310000000000000,5529319999999999999,00000001311,MCP,MCC,2,MCP,ESP
DCN,20140404,6504260000000000000,06,16,16,006,1
DDB,20140404,6504260000000000000,06,16,16,006,1
DCO,20140404,6543210000000000000,06,16,16,010,1

Adding New formats (DEV):

At the end of BinDataStore.cs you'll find LoadBinDir() which will find all the files and attempt to parse their names, filtering out the ignored files.  Names that are parsed properly are then sent into a large switch statement.  You'll need to create a new class to do your parsing and call it from inside this switch passing in the file name.

The bin data should be stored within the BinDataStore class.  You'll need to accomplish this using your best judgment giving the data being loaded.  If needed update the GetCardData method to perform a look up on your data after the issuer has been identified.

Test Data:

With the bin data attached loaded into service the following data is valid.
BinClient bc = new BinClient();
CardData tmp = bc.GetCardDataFromPAN("401288888888188A", "1299");
Assert.AreEqual("", tmp.Issuer);
Assert.IsTrue(0 == tmp.Capabilities);
Assert.AreEqual(ResultCode.BadCard, tmp.Result);
Assert.AreEqual("Card number must be between 8 and 20 digits.", tmp.Message);
Assert.AreEqual(0, tmp.DebitNetworks.Count);

tmp = bc.GetCardDataFromPAN("0000888888881883", "1299");
Assert.AreEqual("", tmp.Issuer);
Assert.IsTrue(0 == tmp.Capabilities);
Assert.AreEqual(ResultCode.BinNotFound, tmp.Result);
Assert.AreEqual("Issuer not found.", tmp.Message);
Assert.AreEqual(0, tmp.DebitNetworks.Count);

tmp = bc.GetCardDataFromPAN("4012888888881881", "1299");
Assert.AreEqual("Visa", tmp.Issuer);
Assert.AreEqual(Capability.Credit, tmp.Capabilities);
Assert.AreEqual(ResultCode.Found, tmp.Result);
Assert.AreEqual("", tmp.Message);
Assert.AreEqual(0, tmp.DebitNetworks.Count);

tmp = bc.GetCardDataFromPAN("6011000012345678", "1299");
Assert.AreEqual("Discover", tmp.Issuer);
Assert.AreEqual(Capability.Credit, tmp.Capabilities);
Assert.AreEqual(ResultCode.Found, tmp.Result);
Assert.AreEqual("", tmp.Message);
Assert.AreEqual(0, tmp.DebitNetworks.Count);

tmp = bc.GetCardDataFromPAN("4001271234567897", "1299");
Assert.AreEqual("Visa", tmp.Issuer);
Assert.AreEqual(Capability.Credit | Capability.LVL2, tmp.Capabilities);
Assert.AreEqual(ResultCode.Found, tmp.Result);
Assert.AreEqual("", tmp.Message);
Assert.AreEqual(0, tmp.DebitNetworks.Count);

tmp = bc.GetCardDataFromPAN("4002660123456783", "1299");
Assert.AreEqual("Visa", tmp.Issuer);
Assert.AreEqual(Capability.Credit | Capability.Debit, tmp.Capabilities);
Assert.AreEqual(ResultCode.Found, tmp.Result);
Assert.AreEqual("", tmp.Message);
Assert.AreEqual(3, tmp.DebitNetworks.Count);

tmp = bc.GetCardDataFromBIN("547620", 16, "1250");
Assert.AreEqual("MasterCard", tmp.Issuer);
Assert.AreEqual("LUX", tmp.CountryCode);
Assert.AreEqual(Capability.Credit | Capability.LVL2, tmp.Capabilities);
Assert.AreEqual(ResultCode.Found, tmp.Result);
Assert.AreEqual("", tmp.Message);

 

Comments