| /******************************************************************************* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| *******************************************************************************/ |
| package org.apache.ofbiz.accounting.thirdparty.gosoftware; |
| |
| import java.io.IOException; |
| import java.math.BigDecimal; |
| import java.util.List; |
| import java.util.Locale; |
| import java.util.Map; |
| import java.util.Properties; |
| |
| import org.apache.ofbiz.accounting.payment.PaymentGatewayServices; |
| import org.apache.ofbiz.base.util.Debug; |
| import org.apache.ofbiz.base.util.GeneralException; |
| import org.apache.ofbiz.base.util.StringUtil; |
| import org.apache.ofbiz.base.util.UtilMisc; |
| import org.apache.ofbiz.base.util.UtilNumber; |
| import org.apache.ofbiz.base.util.UtilProperties; |
| import org.apache.ofbiz.base.util.UtilValidate; |
| import org.apache.ofbiz.entity.Delegator; |
| import org.apache.ofbiz.entity.GenericValue; |
| import org.apache.ofbiz.entity.util.EntityUtilProperties; |
| import org.apache.ofbiz.service.DispatchContext; |
| import org.apache.ofbiz.service.ServiceUtil; |
| |
| |
| public class PcChargeServices { |
| |
| public static final String module = PcChargeServices.class.getName(); |
| private static int decimals = UtilNumber.getBigDecimalScale("invoice.decimals"); |
| private static int rounding = UtilNumber.getBigDecimalRoundingMode("invoice.rounding"); |
| public final static String resource = "AccountingUiLabels"; |
| |
| public static Map<String, Object> ccAuth(DispatchContext dctx, Map<String, ? extends Object> context) { |
| Locale locale = (Locale) context.get("locale"); |
| Delegator delegator = dctx.getDelegator(); |
| // setup the PCCharge Interface |
| Properties props = buildPccProperties(context, delegator); |
| PcChargeApi api = getApi(props); |
| if (api == null) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resource, |
| "AccountingPcChargeErrorGettingPaymentGatewayConfig", locale)); |
| } |
| |
| try { |
| PcChargeServices.setCreditCardInfo(api, context); |
| } catch (GeneralException e) { |
| return ServiceUtil.returnError(e.getMessage()); |
| } |
| |
| // basic tx info |
| api.set(PcChargeApi.TRANS_AMOUNT, getAmountString(context, "processAmount")); |
| api.set(PcChargeApi.TICKET_NUM, context.get("orderId")); |
| api.set(PcChargeApi.MANUAL_FLAG, "0"); |
| api.set(PcChargeApi.PRESENT_FLAG, "1"); |
| |
| // command setting |
| if ("1".equals(props.getProperty("autoBill"))) { |
| // sale |
| api.set(PcChargeApi.COMMAND, "1"); |
| } else { |
| // pre-auth |
| api.set(PcChargeApi.COMMAND, "4"); |
| } |
| |
| // send the transaction |
| PcChargeApi out = null; |
| try { |
| out = api.send(); |
| } catch (IOException e) { |
| Debug.logError(e, module); |
| return ServiceUtil.returnError(e.getMessage()); |
| } catch (GeneralException e) { |
| Debug.logError(e, module); |
| return ServiceUtil.returnError(e.getMessage()); |
| } |
| |
| if (out != null) { |
| Map<String, Object> result = ServiceUtil.returnSuccess(); |
| String resultCode = out.get(PcChargeApi.RESULT); |
| boolean passed = false; |
| if ("CAPTURED".equals(resultCode)) { |
| result.put("authResult", Boolean.TRUE); |
| result.put("captureResult", Boolean.TRUE); |
| passed = true; |
| } else if ("APPROVED".equals(resultCode)) { |
| result.put("authCode", out.get(PcChargeApi.AUTH_CODE)); |
| result.put("authResult", Boolean.TRUE); |
| passed = true; |
| } else if ("PROCESSED".equals(resultCode)) { |
| result.put("authResult", Boolean.TRUE); |
| } else { |
| result.put("authResult", Boolean.FALSE); |
| } |
| |
| result.put("authRefNum", out.get(PcChargeApi.TROUTD) != null ? out.get(PcChargeApi.TROUTD) : ""); |
| result.put("processAmount", context.get("processAmount")); |
| result.put("authCode", out.get(PcChargeApi.AUTH_CODE)); |
| result.put("authFlag", out.get(PcChargeApi.REFERENCE)); |
| result.put("authMessage", out.get(PcChargeApi.RESULT)); |
| result.put("cvCode", out.get(PcChargeApi.CVV2_CODE)); |
| result.put("avsCode", out.get(PcChargeApi.AVS_CODE)); |
| |
| if (!passed) { |
| String respMsg = out.get(PcChargeApi.RESULT) + " / " + out.get(PcChargeApi.AUTH_CODE); |
| String refNum = out.get(PcChargeApi.TROUTD); |
| result.put("customerRespMsgs", UtilMisc.toList(respMsg, refNum)); |
| } |
| |
| if (result.get("captureResult") != null) { |
| result.put("captureCode", out.get(PcChargeApi.AUTH_CODE)); |
| result.put("captureFlag", out.get(PcChargeApi.REFERENCE)); |
| result.put("captureRefNum", out.get(PcChargeApi.TROUTD)); |
| result.put("captureMessage", out.get(PcChargeApi.RESULT)); |
| } |
| |
| return result; |
| |
| } else { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resource, |
| "AccountingPcChargeResultIsNull", locale)); |
| } |
| } |
| |
| public static Map<String, Object> ccCapture(DispatchContext dctx, Map<String, ? extends Object> context) { |
| GenericValue orderPaymentPreference = (GenericValue) context.get("orderPaymentPreference"); |
| Locale locale = (Locale) context.get("locale"); |
| Delegator delegator = dctx.getDelegator(); |
| //lets see if there is a auth transaction already in context |
| GenericValue authTransaction = (GenericValue) context.get("authTrans"); |
| |
| if (authTransaction == null) { |
| authTransaction = PaymentGatewayServices.getAuthTransaction(orderPaymentPreference); |
| } |
| |
| if (authTransaction == null) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resource, |
| "AccountingPaymentTransactionAuthorizationNotFoundCannotCapture", locale)); |
| } |
| |
| // setup the PCCharge Interface |
| Properties props = buildPccProperties(context, delegator); |
| PcChargeApi api = getApi(props); |
| if (api == null) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resource, |
| "AccountingPcChargeErrorGettingPaymentGatewayConfig", locale)); |
| } |
| |
| api.set(PcChargeApi.TROUTD, authTransaction.getString("referenceNum")); |
| api.set(PcChargeApi.COMMAND, "5"); |
| |
| // send the transaction |
| PcChargeApi out = null; |
| try { |
| out = api.send(); |
| } catch (IOException e) { |
| Debug.logError(e, module); |
| return ServiceUtil.returnError(e.getMessage()); |
| } catch (GeneralException e) { |
| Debug.logError(e, module); |
| return ServiceUtil.returnError(e.getMessage()); |
| } |
| |
| if (out != null) { |
| Map<String, Object> result = ServiceUtil.returnSuccess(); |
| String resultCode = out.get(PcChargeApi.RESULT); |
| if ("CAPTURED".equals(resultCode)) { |
| result.put("captureResult", Boolean.TRUE); |
| } else { |
| result.put("captureResult", Boolean.FALSE); |
| } |
| result.put("captureAmount", context.get("captureAmount")); |
| result.put("captureRefNum", out.get(PcChargeApi.TROUTD) != null ? out.get(PcChargeApi.TROUTD) : ""); |
| result.put("captureCode", out.get(PcChargeApi.AUTH_CODE)); |
| result.put("captureFlag", out.get(PcChargeApi.REFERENCE)); |
| result.put("captureMessage", out.get(PcChargeApi.RESULT)); |
| |
| return result; |
| } else { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resource, |
| "AccountingPcChargeResultIsNull", locale)); |
| } |
| } |
| |
| public static Map<String, Object> ccRelease(DispatchContext dctx, Map<String, ? extends Object> context) { |
| GenericValue orderPaymentPreference = (GenericValue) context.get("orderPaymentPreference"); |
| Delegator delegator = dctx.getDelegator(); |
| //lets see if there is a auth transaction already in context |
| GenericValue authTransaction = (GenericValue) context.get("authTrans"); |
| Locale locale = (Locale) context.get("locale"); |
| |
| if (authTransaction == null) { |
| authTransaction = PaymentGatewayServices.getAuthTransaction(orderPaymentPreference); |
| } |
| |
| if (authTransaction == null) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resource, |
| "AccountingPaymentTransactionAuthorizationNotFoundCannotRelease", locale)); |
| } |
| |
| // setup the PCCharge Interface |
| Properties props = buildPccProperties(context, delegator); |
| PcChargeApi api = getApi(props); |
| if (api == null) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resource, |
| "AccountingPcChargeErrorGettingPaymentGatewayConfig", locale)); |
| } |
| |
| api.set(PcChargeApi.TROUTD, authTransaction.getString("referenceNum")); |
| api.set(PcChargeApi.COMMAND, "3"); |
| |
| // check to make sure we are configured for SALE mode |
| if (!"true".equalsIgnoreCase(props.getProperty("autoBill"))) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resource, |
| "AccountingPcChargeCannotSupportReleasingPreAuth", locale)); |
| } |
| |
| // send the transaction |
| PcChargeApi out = null; |
| try { |
| out = api.send(); |
| } catch (IOException e) { |
| Debug.logError(e, module); |
| return ServiceUtil.returnError(e.getMessage()); |
| } catch (GeneralException e) { |
| Debug.logError(e, module); |
| return ServiceUtil.returnError(e.getMessage()); |
| } |
| |
| if (out != null) { |
| Map<String, Object> result = ServiceUtil.returnSuccess(); |
| String resultCode = out.get(PcChargeApi.RESULT); |
| if ("VOIDED".equals(resultCode)) { |
| result.put("releaseResult", Boolean.TRUE); |
| } else { |
| result.put("releaseResult", Boolean.FALSE); |
| } |
| result.put("releaseAmount", context.get("releaseAmount")); |
| result.put("releaseRefNum", out.get(PcChargeApi.TROUTD) != null ? out.get(PcChargeApi.TROUTD) : ""); |
| result.put("releaseCode", out.get(PcChargeApi.AUTH_CODE)); |
| result.put("releaseFlag", out.get(PcChargeApi.REFERENCE)); |
| result.put("releaseMessage", out.get(PcChargeApi.RESULT)); |
| |
| return result; |
| } else { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resource, |
| "AccountingPcChargeResultIsNull", locale)); |
| } |
| } |
| |
| public static Map<String, Object> ccRefund(DispatchContext dctx, Map<String, ? extends Object> context) { |
| GenericValue orderPaymentPreference = (GenericValue) context.get("orderPaymentPreference"); |
| Delegator delegator = dctx.getDelegator(); |
| //lets see if there is a auth transaction already in context |
| GenericValue authTransaction = (GenericValue) context.get("authTrans"); |
| Locale locale = (Locale) context.get("locale"); |
| |
| if (authTransaction == null) { |
| authTransaction = PaymentGatewayServices.getAuthTransaction(orderPaymentPreference); |
| } |
| |
| if (authTransaction == null) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resource, |
| "AccountingPaymentTransactionAuthorizationNotFoundCannotRefund", locale)); |
| } |
| |
| // setup the PCCharge Interface |
| Properties props = buildPccProperties(context, delegator); |
| PcChargeApi api = getApi(props); |
| if (api == null) { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resource, |
| "AccountingPcChargeErrorGettingPaymentGatewayConfig", locale)); |
| } |
| |
| api.set(PcChargeApi.TROUTD, authTransaction.getString("referenceNum")); |
| api.set(PcChargeApi.COMMAND, "2"); |
| |
| // send the transaction |
| PcChargeApi out = null; |
| try { |
| out = api.send(); |
| } catch (IOException e) { |
| Debug.logError(e, module); |
| return ServiceUtil.returnError(e.getMessage()); |
| } catch (GeneralException e) { |
| Debug.logError(e, module); |
| return ServiceUtil.returnError(e.getMessage()); |
| } |
| |
| if (out != null) { |
| Map<String, Object> result = ServiceUtil.returnSuccess(); |
| String resultCode = out.get(PcChargeApi.RESULT); |
| if ("CAPTURED".equals(resultCode)) { |
| result.put("refundResult", Boolean.TRUE); |
| } else { |
| result.put("refundResult", Boolean.FALSE); |
| } |
| result.put("refundAmount", context.get("releaseAmount")); |
| result.put("refundRefNum", out.get(PcChargeApi.TROUTD) != null ? out.get(PcChargeApi.TROUTD) : ""); |
| result.put("refundCode", out.get(PcChargeApi.AUTH_CODE)); |
| result.put("refundFlag", out.get(PcChargeApi.REFERENCE)); |
| result.put("refundMessage", out.get(PcChargeApi.RESULT)); |
| |
| return result; |
| } else { |
| return ServiceUtil.returnError(UtilProperties.getMessage(resource, |
| "AccountingPcChargeResultIsNull", locale)); |
| } |
| } |
| |
| private static void setCreditCardInfo(PcChargeApi api, Map<String, ? extends Object> context) throws GeneralException { |
| GenericValue orderPaymentPreference = (GenericValue) context.get("orderPaymentPreference"); |
| GenericValue creditCard = (GenericValue) context.get("creditCard"); |
| if (creditCard != null) { |
| List<String> expDateList = StringUtil.split(creditCard.getString("expireDate"), "/"); |
| String month = expDateList.get(0); |
| String year = expDateList.get(1); |
| String y2d = year.substring(2); |
| String expDate = month + y2d; |
| |
| String title = creditCard.getString("titleOnCard"); |
| String fname = creditCard.getString("firstNameOnCard"); |
| String mname = creditCard.getString("middleNameOnCard"); |
| String lname = creditCard.getString("lastNameOnCard"); |
| String sufix = creditCard.getString("suffixOnCard"); |
| StringBuilder name = new StringBuilder(); |
| if (UtilValidate.isNotEmpty(title)) { |
| name.append(title).append(" "); |
| } |
| if (UtilValidate.isNotEmpty(fname)) { |
| name.append(fname).append(" "); |
| } |
| if (UtilValidate.isNotEmpty(mname)) { |
| name.append(mname).append(" "); |
| } |
| if (UtilValidate.isNotEmpty(lname)) { |
| name.append(lname).append(" "); |
| } |
| if (UtilValidate.isNotEmpty(sufix)) { |
| name.append(sufix); |
| } |
| String nameOnCard = name.toString().trim(); |
| String acctNumber = "F" + creditCard.getString("cardNumber"); |
| String cvNum = (String) context.get("cardSecurityCode"); |
| |
| api.set(PcChargeApi.ACCT_NUM, acctNumber); |
| api.set(PcChargeApi.EXP_DATE, expDate); |
| api.set(PcChargeApi.CARDHOLDER, nameOnCard); |
| if (UtilValidate.isNotEmpty(cvNum)) { |
| api.set(PcChargeApi.CVV2, cvNum); |
| } |
| |
| // billing address information |
| GenericValue billingAddress = (GenericValue) context.get("billingAddress"); |
| if (billingAddress != null) { |
| api.set(PcChargeApi.STREET, billingAddress.getString("address1")); |
| api.set(PcChargeApi.ZIP_CODE, billingAddress.getString("postalCode")); |
| } else { |
| String zipCode = orderPaymentPreference.getString("billingPostalCode"); |
| if (UtilValidate.isNotEmpty(zipCode)) { |
| api.set(PcChargeApi.ZIP_CODE, zipCode); |
| } |
| } |
| } else { |
| throw new GeneralException("No CreditCard object found"); |
| } |
| } |
| |
| private static PcChargeApi getApi(Properties props) { |
| if (props == null) { |
| Debug.logError("Cannot load API w/ null properties", module); |
| return null; |
| } |
| String host = props.getProperty("host"); |
| int port = 0; |
| try { |
| port = Integer.parseInt(props.getProperty("port")); |
| } catch (Exception e) { |
| Debug.logError(e, module); |
| } |
| PcChargeApi api = null; |
| if (port > 0 && host != null) { |
| api = new PcChargeApi(host, port); |
| } else { |
| api = new PcChargeApi(); |
| } |
| |
| api.set(PcChargeApi.PROCESSOR_ID, props.getProperty("processorID")); |
| api.set(PcChargeApi.MERCH_NUM, props.getProperty("merchantID")); |
| api.set(PcChargeApi.USER_ID, props.getProperty("userID")); |
| return api; |
| } |
| |
| private static Properties buildPccProperties(Map<String, ? extends Object> context, Delegator delegator) { |
| String configString = (String) context.get("paymentConfig"); |
| if (configString == null) { |
| configString = "payment.properties"; |
| } |
| |
| String processorId = EntityUtilProperties.getPropertyValue(configString, "payment.pccharge.processorID", delegator); |
| String merchantId = EntityUtilProperties.getPropertyValue(configString, "payment.pccharge.merchantID", delegator); |
| String userId = EntityUtilProperties.getPropertyValue(configString, "payment.pccharge.userID", delegator); |
| String host = EntityUtilProperties.getPropertyValue(configString, "payment.pccharge.host", delegator); |
| String port = EntityUtilProperties.getPropertyValue(configString, "payment.pccharge.port", delegator); |
| String autoBill = EntityUtilProperties.getPropertyValue(configString, "payment.pccharge.autoBill", "true", delegator); |
| |
| // some property checking |
| if (UtilValidate.isEmpty(processorId)) { |
| Debug.logWarning("The processorID property in [" + configString + "] is not configured", module); |
| return null; |
| } |
| if (UtilValidate.isEmpty(merchantId)) { |
| Debug.logWarning("The merchantID property in [" + configString + "] is not configured", module); |
| return null; |
| } |
| if (UtilValidate.isEmpty(userId)) { |
| Debug.logWarning("The userID property in [" + configString + "] is not configured", module); |
| return null; |
| } |
| |
| // create some properties for CS Client |
| Properties props = new Properties(); |
| props.put("processorID", processorId); |
| props.put("merchantID", merchantId); |
| props.put("userID", userId); |
| props.put("host", host); |
| props.put("port", port); |
| props.put("autoBill", autoBill); |
| Debug.logInfo("Returning properties - " + props, module); |
| |
| return props; |
| } |
| |
| private static String getAmountString(Map<String, ? extends Object> context, String amountField) { |
| BigDecimal processAmount = (BigDecimal) context.get(amountField); |
| return processAmount.setScale(decimals, rounding).toPlainString(); |
| } |
| |
| } |