/* This file is part of OpenMyEWB. OpenMyEWB is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. OpenMyEWB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenMyEWB. If not, see <http://www.gnu.org/licenses/>. OpenMyEWB is Copyright 2005-2009 Nicolas Kruchten (nicolas@kruchten.com), Francis Kung, Engineers Without Borders Canada, Michael Trauttmansdorff, Jon Fishbein, David Kadish */ package ca.myewb.frame; import java.io.IOException; import java.io.StringWriter; import java.io.UnsupportedEncodingException; import java.net.MalformedURLException; import java.util.Calendar; import java.util.Date; import java.util.Hashtable; import java.util.List; import java.util.Vector; import org.apache.velocity.Template; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.Velocity; import ca.myewb.model.EmailModel; import ca.myewb.model.UserModel; public class CreditCardTransaction { private Hashtable<String, String> input = new Hashtable<String, String>(); private Hashtable<String, String> output = new Hashtable<String, String>(); private float totalAmount = 0; private int itemCount = 0; private boolean attempted = false; private boolean succeeded = false; private String orderNumber; private Date date = null; public Date getDate() { return date; } public void setCardInfo(String owner, String number, String month, String year) { input.put("trnCardOwner", owner); input.put("trnCardNumber", number); input.put("trnExpMonth", month); input.put("trnExpYear", year); } public void setContactInfo(String name, String email, String phone, String address) { input.put("ordName", name); input.put("ordEmailAddress", email); input.put("ordPhoneNumber", phone); String[] splitAddress = address.split("\n"); input.put("ordAddress1", (splitAddress.length > 0 && splitAddress[0] != null) ? splitAddress[0] : ""); input.put("ordAddress2", (splitAddress.length > 2 && splitAddress[2] != null) ? splitAddress[2] : ""); input.put("ordCity", (splitAddress.length > 3 && splitAddress[3] != null) ? splitAddress[3] : ""); input.put("ordProvince", (splitAddress.length > 4 && splitAddress[4] != null) ? splitAddress[4] : ""); input.put("ordPostalCode", (splitAddress.length > 5 && splitAddress[5] != null) ? splitAddress[5] : ""); input.put("ordCountry", (splitAddress.length > 6 && splitAddress[6] != null) ? splitAddress[6] : ""); } public void setContactInfo(UserModel user) { input.put("ordName", user.getFirstname() + " " + user.getLastname()); input.put("ordEmailAddress", user.getEmail()); input.put("ordPhoneNumber", user.getPhone()); input.put("ordAddress1", user.getAddress1() + ", " + user.getSuite()); input.put("ordAddress2", user.getAddress2()); input.put("ordCity", user.getCity()); input.put("ordProvince", user.getProvince()); input.put("ordPostalCode", user.getPostalcode()); input.put("ordCountry", user.getCountry()); } public void addItem(String sku, int quantity, float cost, String name) { itemCount++; input.put("prod_id_" + itemCount, sku); input.put("prod_quantity_" + itemCount, new Integer(quantity).toString()); input.put("prod_name_" + itemCount, name); input.put("prod_cost_" + itemCount, new Float(cost).toString()); totalAmount += quantity*cost; } public void showOutput() { //for debugging purposes for(String key: output.keySet()) { System.out.println(key + " = " + output.get(key)); } } public void attemptTransaction(String trnPrefix) throws UnsupportedEncodingException, MalformedURLException, IOException { input.put("trnAmount", new Float(totalAmount).toString()); orderNumber = trnPrefix + "-" + new Long(System.currentTimeMillis()).toString(); input.put("trnOrderNumber", orderNumber); /* SAMPLE CODE -- REPLACE WITH YOUR OWN PROCESSOR'S INTEGRATION CODE //add these hard-coded bits input.put("requestType", "BACKEND"); input.put("merchant_id", "MERCHANT ID GOES HERE"); //convert input hashtable into url string String inputString = ""; for(String key: input.keySet()) { inputString += URLEncoder.encode(key, "UTF-8") + "=" + URLEncoder.encode(input.get(key), "UTF-8") + "&"; } //set up the connection URL url = new URL( "https://www.beanstream.com/scripts/process_transaction.asp" ); URLConnection conn = url.openConnection(); conn.setDoOutput( true ); //send the input string OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream()); wr.write(inputString); wr.flush(); // grab the output string BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream())); String outputString = ""; String line; while ((line = rd.readLine()) != null) { outputString += line; } wr.close(); rd.close(); //convert the output string into an output hashtable String[] kvPairs = outputString.split("&"); for(String pair: kvPairs) { try { String[] kv = pair.split("="); output.put(URLDecoder.decode(kv[0], "UTF-8"), URLDecoder.decode(kv[1], "UTF-8")); } catch(ArrayIndexOutOfBoundsException e) { ; } } */ //the 2 following lines are placeholders output.put("errorType", "Y"); output.put("messageText", "Credit card process integration not implemented"); attempted = true; date = new Date(); if(output.get("errorType").equals("N") && output.get("messageText").equals("Approved")) { succeeded = true; } else { succeeded = false; } } public boolean isAttempted() { return attempted; } public boolean isSucceeded() { if(!attempted) { throw new IllegalStateException(); } return succeeded; } public Hashtable<String, String> getOutput() { if(!attempted) { throw new IllegalStateException(); } return output; } public String getOrderNumber() { return orderNumber; } public float getTotalAmount() { return totalAmount; } public String getEmail() { return input.get("ordEmailAddress"); } public String getName() { return input.get("ordName"); } public List<Hashtable<String, String>> getItems() { Vector<Hashtable<String, String>> items = new Vector<Hashtable<String, String>>(); for(int i=1; i <= itemCount; i++) { Hashtable<String, String> item = new Hashtable<String, String>(); item.put("sku", input.get("prod_id_" + i)); item.put("quantity", input.get("prod_quantity_" + i)); item.put("name", input.get("prod_name_" + i)); item.put("cost", input.get("prod_cost_" + i)); items.add(item); } return items; } public static String checkCardType(String cardType, String cardNum) { if (cardType.equals("visa")) { if (cardNum.length() != 16 || cardNum.charAt(0) != '4') { return "This number is not a Visa number"; } } else if (cardType.equals("mc")) { if (cardNum.length() != 16 || (!cardNum.substring(0, 2).equals("36") && (cardNum.charAt(0) != '5' || Integer.parseInt(cardNum.substring(1, 2)) >= 6))) { return "This number is not a MasterCard number"; } } else if (cardType.equals("amex")) { if (cardNum.length() != 15 || (!cardNum.substring(0, 2).equals("34") && !cardNum.substring(0, 2).equals("37"))) { return "This number is not an American Express number"; } } else { return "Unknown Card type"; } return null; } public static boolean checkCardNo(String cardNum) { int oddoeven = cardNum.length() & 1; int sum = 0; for (int i = 0; i < cardNum.length(); i++) { int digit = cardNum.charAt(i) - '0'; if (((i & 1) ^ oddoeven) == 0) { digit *= 2; if (digit > 9) digit -= 9; } sum += digit; } if (sum % 10 == 0) return true; else return false; } public static String checkExpiry(String expiryStr) { if(expiryStr.length() != 4) { return "Please use MMYY format when entering the expiry date"; } int month = 0; int year = 0; try { month = Integer.parseInt(expiryStr.substring(0,2)); year = 2000 + Integer.parseInt(expiryStr.substring(2)); } catch (Exception e) { return "Please use MMYY format when entering the expiry date"; } Calendar cal = Calendar.getInstance(); if((year < cal.get(Calendar.YEAR)) || ((month-1 < cal.get(Calendar.MONTH)) && (year == cal.get(Calendar.YEAR)))) { return "Your card has expired, please check the date or use another card."; } return null; } public void sendReceipt(String subject) throws Exception { String bodyText = doTemplateMerge("emails/receipt.txt.vm"); String bodyHTML = doTemplateMerge("emails/receipt.html.vm"); Vector<String> emailAddress = new Vector<String>(); emailAddress.add(getEmail()); EmailModel.sendEmail(Helpers.getSystemEmail(), emailAddress, "[" + Helpers.getEnShortName() + "-receipt] Credit Card Transaction Receipt: " + subject, bodyText, bodyHTML, "receipt", false); } private String doTemplateMerge(String templatePath) throws Exception { Template template = Velocity.getTemplate(templatePath); VelocityContext ctx = new VelocityContext(); ctx.put("txn", this); ctx.put("helpers", new Helpers()); StringWriter writer = new StringWriter(); template.merge(ctx, writer); String toString = writer.toString(); return toString; } }