in Programming, Work&Life

Cashcard transaction history read software

Developed the software for reading the cash card transaction history, functions include read the balance, CAN no., issue date, expire date, expenses, and transaction history displayed in crystal report, and can print out in paper. The software screen shot is as,

Cashcard_read

Following are the work done for the software development,

1, cash card read APDU command,

00A40000020118 (select cashcard DF)

803200030400000000 (read the balance)

00B0810010 (read card information file 0001, includes CAN no., maximum transaction number, issue date, expire period, etc.)

00B0850010 (read cash card transaction history in file 0005, P2 is the offset, needs multiply by 4,  it’s a binary file, 10 bytes one transaction records.)

2, utilize the visual studio C#, and the Smart Card framework developed by Olivier Rouit, you can get the source codehere, pcsc based.

3, utilize the crystal report without database, but with the data source, by reading the maximum 25 transaction records from cash card, build up the data source by following code,

     DataSet1 ds = new DataSet1();
     DataTable t = ds.Tables.Add("Transactions");
     t.Columns.Add("item", Type.GetType("System.Int16"));
     t.Columns.Add("Date", Type.GetType("System.String"));
     t.Columns.Add("Time", Type.GetType("System.String"));
     t.Columns.Add("Type", Type.GetType("System.String"));
     t.Columns.Add("Amount", Type.GetType("System.Decimal"));
     t.Columns.Add("Merchant", Type.GetType("System.String"));
     DataRow r;

     for (int i = 1; i <= iCard.GetMaxTranLogNum(); i++)
     {
        r = t.NewRow();

        r["item"] = i;
        r["Date"] = trans[i - 1].TransactionTime.ToString("d", System.Globalization.CultureInfo.CreateSpecificCulture("en-US"));
        r["Time"] = trans[i - 1].TransactionTime.ToString("T", System.Globalization.CultureInfo.CreateSpecificCulture("en-us"));
        r["Type"] = trans[i - 1].TransactionType;
        r["Amount"] = trans[i - 1].TransactionAmount;
        r["Merchant"] = trans[i - 1].MerchantShortName;
        t.Rows.Add(r);
     }

4, set the dynamic TextObject in the Crystal report by following code,

     (objRpt.Section1.ReportObjects["Text9"] as TextObject).Text = ByteArrayToString(CanNo);
     (objRpt.Section1.ReportObjects["Text13"] as TextObject).Text = "S$ " + (num / 100).ToString("0.00");
     (objRpt.Section1.ReportObjects["Text15"] as TextObject).Text = dt.ToString("D");
     (objRpt.Section1.ReportObjects["Text17"] as TextObject).Text = expiredt.ToString("D");
     (objRpt.Section1.ReportObjects["Text19"] as TextObject).Text = "S$ " + iCard.GetExpenses().ToString("0.00");

5, the Julian date in cash card is from the date 1st Jan 1995 12:00 AM,

      public DateTime GetJuliaDateTime(byte [] input)
      {
         DateTime result = DateTime.Now;
         byte[] buffer = new byte[4];
         Array.Copy(input, 0, buffer, 0, 4);       

         if (BitConverter.IsLittleEndian)
            Array.Reverse(buffer); //need the bytes in the reverse order
         int year=1995, month=1;
         int value = BitConverter.ToInt32(buffer, 0);
         int duration = (value / 3600 / 24)+1;
         int[] daysOfMonth = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
         while ((duration > 365 && year % 4 != 0) || (duration > 366 && year % 4 == 0))
         {
            if (year % 4 != 0) duration -= 365;
                else duration -= 366;
        year++;
         }

         for (int i = 0; i < 12; i++)
         {
            if ((year % 4 != 0 && duration > daysOfMonth[i]) ||
            (year % 4 == 0 && i != 1 && duration > daysOfMonth[i]) ||
            (year % 4 == 0 && i == 1 && duration > 29))
            {
               if (year % 4 == 0 && i == 1) duration -= 29;
                 else duration -= daysOfMonth[i];
               month++;
            }
            else
            {
               break;
            }
        }

        result = new DateTime(year, month, duration, (value / 3600) % 24, (value / 60) % 60, value % 60, DateTimeKind.Local);
        return result;
     }

6, the merchant name is not stored in the cash card, only the short code available, have no idea where to get the merchant name, so have to get this information from  software downloaded from Nets website and read the real cash card to get the merchant name, and put in my software.

7, developed the CashCard class derived from CardNative and ICard from the Smart Card Framework, all the reading cash card implementation was put inside the CashCard class.

 


Update on 14th May 2019

From time to time, I received request to share the software. Please find below Link to download,
Cepas CashCard Read Software Download

Note:
1, You can use installation exe file to install under folder: “Publish CashCard Read”
2, or you can use the exe file to open the software directly under folder, “Cepas Read Release”
3, there are some prerequisites for the usage of the software, you might not need to install any of them. But if your system doesn’t have the component, you may need to install. It’s all in the same package.
a, .Net Framework 3.5 sp1, “dotnetfx35_full.exe” or “dotnetfx35setup.exe”, either one.
b, Crystal report componet. “crbasic2008sp1 full.exe” or “CRRedist2008_x64.msi”, either one.
c, WindowsInstaller, WindowsInstaller-KB893803-v2-x86.exe or WindowsServer2003-KB942288-v4-x64.exe

Leave a Reply for Zen Cancel Reply

Write a Comment

Comment

11 Comments

  1. Hi Eric,

    Are you able to send me the software? It will be good for me to extract my cashcash records for claim purposes

  2. Hi hi! Could you pls share with me your software. I’m suspecting I’m getting deducted incorrectly. Thank you!

  3. Hi, Can i get the software. because my company need to record those cashcard expanses. any chance to get back last year records?