package org.dicadeveloper.weplantaforest.payment; import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.HttpHost; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpPost; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.conn.DefaultProxyRoutePlanner; import org.apache.http.message.BasicNameValuePair; import org.dicadeveloper.weplantaforest.cart.Cart; import org.dicadeveloper.weplantaforest.support.Uris; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.env.Environment; import org.springframework.stereotype.Component; import lombok.NonNull; @Component public class PaymentHelper { protected final Log LOG = LogFactory.getLog(PaymentHelper.class.getName()); @Autowired private @NonNull Environment _env; public static final String DEFAULT_ENCODING = "UTF-8"; private final static DecimalFormat priceFormat = new DecimalFormat("#0.00"); private final static String CONNECTION_ERROR = "connection_error"; private final static String UNDEFINED_ERROR = "Es ist ein Fehler aufgetreten. Bitte Versuchen Sie es erneut."; public static Map<String, String> BANK_ERRORS = new HashMap<String, String>(); static { BANK_ERRORS.put("BANK_100", "BANK_NO_API"); BANK_ERRORS.put("BANK_101", "BANK_NO_FIRSTNAME"); BANK_ERRORS.put("BANK_102", "BANK_NO_NAME"); BANK_ERRORS.put("BANK_103", "BANK_NO_STREET"); BANK_ERRORS.put("BANK_104", "BANK_NO_COUNTRY"); BANK_ERRORS.put("BANK_105", "BANK_NO_CITY"); BANK_ERRORS.put("BANK_106", "BANK_NO_ZIP"); BANK_ERRORS.put("BANK_107", "BANK_NO_MAIL"); BANK_ERRORS.put("BANK_108", "BANK_NO_VALUE"); BANK_ERRORS.put("BANK_109", "BANK_NO_USAGE"); BANK_ERRORS.put("BANK_110", "BANK_NO_QUITTUNG"); BANK_ERRORS.put("BANK_111", "BANK_NO_PAYMENT_TYPE"); BANK_ERRORS.put("BANK_112", "BANK_NO_SALUTATION"); BANK_ERRORS.put("BANK_201", "BANK_NO_CC_OWNER"); BANK_ERRORS.put("BANK_202", "BANK_NO_CC_NR"); BANK_ERRORS.put("BANK_203", "BANK_NO_CC_DATE"); BANK_ERRORS.put("BANK_204", "BANK_NO_CC_DATE"); BANK_ERRORS.put("BANK_205", "BANK_NO_SECURITY_NUMBER"); BANK_ERRORS.put("BANK_206", "BANK_NO_CC_TYPE"); BANK_ERRORS.put("BANK_401", "BANK_INVALID_IBAN"); BANK_ERRORS.put("BANK_402", "BANK_INVALID_BIC"); BANK_ERRORS.put("BANK_500", "BANK_UNKNOWN_ERROR"); BANK_ERRORS.put("BANK_501", "BANK_UNKNOWN_EMITTER"); BANK_ERRORS.put("BANK_502", "BANK_INVALID_HASH"); BANK_ERRORS.put("BANK_503", "BANK_CUSTOMER_NOT_FOUND"); BANK_ERRORS.put("BANK_504", "BANK_INVALID_ÜARAM_FORMAT"); BANK_ERRORS.put("BANK_506", "BANK_UNKNOWN_TRANSACTION_TYPE"); BANK_ERRORS.put("BANK_507", "BANK_INVALID_ACCOUNT"); BANK_ERRORS.put("BANK_508", "BANK_ACCOUNT_NR_TOO_LONG"); BANK_ERRORS.put("BANK_509", "BANK_ACCOUNT_NR_TOO_SHORT"); BANK_ERRORS.put("BANK_984", "BANK_DOUBLED_DONATION"); BANK_ERRORS.put("BANK_985", "BANK_CC_DENIED"); } public String postRequestSepa(Cart cart, PaymentData paymentData) { String address = _env.getProperty("bfs.url"); try { CloseableHttpClient httpClient; // on staging and production the requests has to be routed // through a proxy if (_env.getProperty("proxy.host") != null) { HttpHost proxy = new HttpHost(_env.getProperty("proxy.host"), Integer.parseInt(_env.getProperty("proxy.port"))); DefaultProxyRoutePlanner routePlanner = new DefaultProxyRoutePlanner(proxy); httpClient = HttpClients.custom() .setRoutePlanner(routePlanner) .build(); } else { httpClient = HttpClients.custom() .build(); } HttpPost httpPost = new HttpPost(address); List<NameValuePair> urlParameters = new ArrayList<NameValuePair>(); Map<String, String> params = createParams(cart, paymentData); for (Entry<String, String> entry : params.entrySet()) { urlParameters.add(new BasicNameValuePair(entry.getKey(), entry.getValue())); } httpPost.setEntity(new UrlEncodedFormEntity(urlParameters)); HttpResponse response = httpClient.execute(httpPost); BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity() .getContent())); StringBuffer result = new StringBuffer(); String line = ""; while ((line = rd.readLine()) != null) { result.append(line); } httpClient.close(); return result.toString(); } catch (final Exception e) { LOG.error("unable to do post request to '" + address + "'", e); return CONNECTION_ERROR; } } public String postRequestCC(Cart cart, PaymentData paymentData) { String address = _env.getProperty("bfs.url"); try { CloseableHttpClient httpClient; // on staging and production the requests has to be routed // through a proxy if (_env.getProperty("proxy.host") != null) { HttpHost proxy = new HttpHost(_env.getProperty("proxy.host"), Integer.parseInt(_env.getProperty("proxy.port"))); DefaultProxyRoutePlanner routePlanner = new DefaultProxyRoutePlanner(proxy); httpClient = HttpClients.custom() .setRoutePlanner(routePlanner) .build(); } else { httpClient = HttpClients.custom() .build(); } HttpPost httpPost = new HttpPost(address); List<NameValuePair> urlParameters = new ArrayList<NameValuePair>(); Map<String, String> params = createParamsCC(cart, paymentData); for (Entry<String, String> entry : params.entrySet()) { urlParameters.add(new BasicNameValuePair(entry.getKey(), entry.getValue())); } httpPost.setEntity(new UrlEncodedFormEntity(urlParameters)); HttpResponse response = httpClient.execute(httpPost); BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity() .getContent())); StringBuffer result = new StringBuffer(); String line = ""; while ((line = rd.readLine()) != null) { result.append(line); } httpClient.close(); return result.toString(); } catch (final Exception e) { LOG.error("unable to do post request to '" + address + "'", e); return CONNECTION_ERROR; } } public boolean isSuccessFull(String result) { return result != null && result.contains("status=success"); } public boolean isSuccessFullCC(String result) { return result != null && result.startsWith("<!DOCTYPE html PUBLIC"); } public boolean isConnectionError(String result) { return result != null && result.equals(CONNECTION_ERROR); } public boolean isUndefinedError(String result) { return result != null && result.equals(UNDEFINED_ERROR); } public String getErrorCode(String response) { return response.substring(response.indexOf("&code=") + 10, response.indexOf("&code=") + 13); } private Map<String, String> createParams(Cart cart, PaymentData paymentData) { Map<String, String> params = new HashMap<>(); // mandatory parameters params.put("charset", DEFAULT_ENCODING); params.put("oid", _env.getProperty("bfs.oid")); String formattedPrice = priceFormat.format(cart.getTotalPrice() .doubleValue()) .toString(); formattedPrice = formattedPrice.replace(",", "."); try { params.put("betrag", URLEncoder.encode(formattedPrice, DEFAULT_ENCODING)); params.put("anrede", URLEncoder.encode(paymentData.getSalutation() .toString(), DEFAULT_ENCODING)); params.put("vorname", URLEncoder.encode(paymentData.getForename(), DEFAULT_ENCODING)); params.put("nachname", URLEncoder.encode(paymentData.getName(), DEFAULT_ENCODING)); params.put("strasse", URLEncoder.encode(paymentData.getStreet(), DEFAULT_ENCODING)); params.put("land", URLEncoder.encode(paymentData.getCountry(), DEFAULT_ENCODING)); params.put("ort", URLEncoder.encode(paymentData.getCity(), DEFAULT_ENCODING)); params.put("plz", URLEncoder.encode(paymentData.getZip(), DEFAULT_ENCODING)); params.put("email", URLEncoder.encode(paymentData.getMail(), DEFAULT_ENCODING)); params.put("verwendungszweck", "Spende I Plant A Tree"); params.put("quittung", URLEncoder.encode(paymentData.getReceipt(), DEFAULT_ENCODING)); params.put("zahlungsart", URLEncoder.encode(paymentData.getPaymentMethod(), DEFAULT_ENCODING)); params.put("sepa_data[iban]", URLEncoder.encode(paymentData.getIban(), DEFAULT_ENCODING)); params.put("sepa_data[bic]", URLEncoder.encode(paymentData.getBic(), DEFAULT_ENCODING)); // optional parameters params.put("ret_success_url", Uris.PAYMENT_SUCCESS); params.put("ret_error_url", Uris.PAYMENT_ERROR); params.put("trackingcode", "Cart-ID: " + cart.getId()); if (null != paymentData.getCompany() && !paymentData.getCompany() .isEmpty()) { params.put("firma", URLEncoder.encode(paymentData.getCompany(), DEFAULT_ENCODING)); } if (null != paymentData.getCompanyAddon() && !paymentData.getCompanyAddon() .isEmpty()) { params.put("firma_zusatz", URLEncoder.encode(paymentData.getCompanyAddon(), DEFAULT_ENCODING)); } if (null != paymentData.getComment() && !paymentData.getComment() .isEmpty()) { params.put("kommentar", URLEncoder.encode(paymentData.getComment(), DEFAULT_ENCODING)); } } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } return params; } private Map<String, String> createParamsCC(Cart cart, PaymentData paymentData) { Map<String, String> params = new HashMap<>(); // mandatory parameters params.put("charset", DEFAULT_ENCODING); params.put("oid", _env.getProperty("bfs.oid")); String formattedPrice = priceFormat.format(cart.getTotalPrice() .doubleValue()) .toString(); formattedPrice = formattedPrice.replace(",", "."); try { params.put("betrag", URLEncoder.encode(formattedPrice, DEFAULT_ENCODING)); params.put("anrede", URLEncoder.encode(paymentData.getSalutation() .toString(), DEFAULT_ENCODING)); params.put("vorname", URLEncoder.encode(paymentData.getForename(), DEFAULT_ENCODING)); params.put("nachname", URLEncoder.encode(paymentData.getName(), DEFAULT_ENCODING)); params.put("strasse", URLEncoder.encode(paymentData.getStreet(), DEFAULT_ENCODING)); params.put("land", URLEncoder.encode(paymentData.getCountry(), DEFAULT_ENCODING)); params.put("ort", URLEncoder.encode(paymentData.getCity(), DEFAULT_ENCODING)); params.put("plz", URLEncoder.encode(paymentData.getZip(), DEFAULT_ENCODING)); params.put("email", URLEncoder.encode(paymentData.getMail(), DEFAULT_ENCODING)); params.put("verwendungszweck", "Spende I Plant A Tree"); params.put("quittung", URLEncoder.encode(paymentData.getReceipt(), DEFAULT_ENCODING)); params.put("zahlungsart", URLEncoder.encode(paymentData.getPaymentMethod(), DEFAULT_ENCODING)); // optional parameters params.put("ret_success_url", URLEncoder.encode(Uris.PAYMENT_SUCCESS, DEFAULT_ENCODING)); params.put("ret_error_url", URLEncoder.encode(Uris.PAYMENT_ERROR, DEFAULT_ENCODING)); params.put("trackingcode", URLEncoder.encode("Cart-ID: " + cart.getId(), DEFAULT_ENCODING)); if (null != paymentData.getCompany() && !paymentData.getCompany() .isEmpty()) { params.put("firma", URLEncoder.encode(paymentData.getCompany(), DEFAULT_ENCODING)); } if (null != paymentData.getCompanyAddon() && !paymentData.getCompanyAddon() .isEmpty()) { params.put("firma_zusatz", URLEncoder.encode(paymentData.getCompanyAddon(), DEFAULT_ENCODING)); } if (null != paymentData.getComment() && !paymentData.getComment() .isEmpty()) { params.put("kommentar", URLEncoder.encode(paymentData.getComment(), DEFAULT_ENCODING)); } } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } return params; } }