use of org.apache.ofbiz.base.util.GeneralException in project ofbiz-framework by apache.
the class GiftCertificateServices method createGiftCertificate.
// Base Gift Certificate Services
public static Map<String, Object> createGiftCertificate(DispatchContext dctx, Map<String, ? extends Object> context) {
LocalDispatcher dispatcher = dctx.getDispatcher();
Delegator delegator = dctx.getDelegator();
Locale locale = (Locale) context.get("locale");
GenericValue userLogin = (GenericValue) context.get("userLogin");
String productStoreId = (String) context.get("productStoreId");
BigDecimal initialAmount = (BigDecimal) context.get("initialAmount");
String currency = (String) context.get("currency");
String partyId = (String) context.get("partyId");
if (UtilValidate.isEmpty(partyId)) {
partyId = "_NA_";
}
String currencyUom = (String) context.get("currency");
if (UtilValidate.isEmpty(currencyUom)) {
currencyUom = EntityUtilProperties.getPropertyValue("general", "currency.uom.id.default", "USD", delegator);
}
String cardNumber = null;
String pinNumber = null;
String refNum = null;
String finAccountId = null;
try {
final String accountName = "Gift Certificate Account";
final String deposit = "DEPOSIT";
GenericValue giftCertSettings = EntityQuery.use(delegator).from("ProductStoreFinActSetting").where("productStoreId", productStoreId, "finAccountTypeId", FinAccountHelper.giftCertFinAccountTypeId).cache().queryOne();
Map<String, Object> acctResult = null;
if ("Y".equals(giftCertSettings.getString("requirePinCode"))) {
// TODO: move this code to createFinAccountForStore as well
int cardNumberLength = CARD_NUMBER_LENGTH;
int pinNumberLength = PIN_NUMBER_LENGTH;
if (giftCertSettings.getLong("accountCodeLength") != null) {
cardNumberLength = giftCertSettings.getLong("accountCodeLength").intValue();
}
if (giftCertSettings.getLong("pinCodeLength") != null) {
pinNumberLength = giftCertSettings.getLong("pinCodeLength").intValue();
}
cardNumber = generateNumber(delegator, cardNumberLength, true);
pinNumber = generateNumber(delegator, pinNumberLength, false);
// in this case, the card number is the finAccountId
finAccountId = cardNumber;
// create the FinAccount
Map<String, Object> acctCtx = UtilMisc.<String, Object>toMap("finAccountId", finAccountId);
acctCtx.put("finAccountTypeId", FinAccountHelper.giftCertFinAccountTypeId);
acctCtx.put("finAccountName", accountName);
acctCtx.put("finAccountCode", pinNumber);
acctCtx.put("userLogin", userLogin);
acctResult = dispatcher.runSync("createFinAccount", acctCtx);
if (ServiceUtil.isError(acctResult)) {
return ServiceUtil.returnError(ServiceUtil.getErrorMessage(acctResult));
}
} else {
Map<String, Object> createAccountCtx = new HashMap<>();
createAccountCtx.put("ownerPartyId", partyId);
createAccountCtx.put("finAccountTypeId", FinAccountHelper.giftCertFinAccountTypeId);
createAccountCtx.put("productStoreId", productStoreId);
createAccountCtx.put("currencyUomId", currency);
createAccountCtx.put("finAccountName", accountName + "for party [" + partyId + "]");
createAccountCtx.put("userLogin", userLogin);
acctResult = dispatcher.runSync("createFinAccountForStore", createAccountCtx);
if (ServiceUtil.isError(acctResult)) {
return ServiceUtil.returnError(ServiceUtil.getErrorMessage(acctResult));
}
if (acctResult.get("finAccountId") != null) {
finAccountId = cardNumber = (String) acctResult.get("finAccountId");
}
if (acctResult.get("finAccountCode") != null) {
cardNumber = (String) acctResult.get("finAccountCode");
}
}
// create the initial (deposit) transaction
// do something tricky here: run as the "system" user
// that can actually create a financial account transaction
GenericValue permUserLogin = EntityQuery.use(delegator).from("UserLogin").where("userLoginId", "system").cache().queryOne();
refNum = createTransaction(delegator, dispatcher, permUserLogin, initialAmount, productStoreId, partyId, currencyUom, deposit, finAccountId, locale);
} catch (GenericEntityException | GenericServiceException e) {
Debug.logError(e, module);
return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "AccountingGiftCerticateNumberCreationError", locale));
} catch (GeneralException e) {
Debug.logError(e, module);
return ServiceUtil.returnError(e.getMessage());
}
Map<String, Object> result = ServiceUtil.returnSuccess();
result.put("cardNumber", cardNumber);
result.put("pinNumber", pinNumber);
result.put("initialAmount", initialAmount);
result.put("processResult", Boolean.TRUE);
result.put("responseCode", "1");
result.put("referenceNum", refNum);
Debug.logInfo("Create GC Result - " + result, module);
return result;
}
use of org.apache.ofbiz.base.util.GeneralException in project ofbiz-framework by apache.
the class PaymentGatewayServices method captureOrderPayments.
/**
* Captures payments through service calls to the defined processing service for the ProductStore/PaymentMethodType
* @return COMPLETE|FAILED|ERROR for complete processing of ALL payment methods.
*/
public static Map<String, Object> captureOrderPayments(DispatchContext dctx, Map<String, ? extends Object> context) {
Delegator delegator = dctx.getDelegator();
LocalDispatcher dispatcher = dctx.getDispatcher();
GenericValue userLogin = (GenericValue) context.get("userLogin");
String orderId = (String) context.get("orderId");
String invoiceId = (String) context.get("invoiceId");
String billingAccountId = (String) context.get("billingAccountId");
BigDecimal amountToCapture = (BigDecimal) context.get("captureAmount");
Locale locale = (Locale) context.get("locale");
amountToCapture = amountToCapture.setScale(decimals, rounding);
// get the order header and payment preferences
GenericValue orderHeader = null;
List<GenericValue> paymentPrefs = null;
List<GenericValue> paymentPrefsBa = null;
try {
orderHeader = EntityQuery.use(delegator).from("OrderHeader").where("orderId", orderId).queryOne();
// get the payment prefs
paymentPrefs = EntityQuery.use(delegator).from("OrderPaymentPreference").where("orderId", orderId, "statusId", "PAYMENT_AUTHORIZED").orderBy("-maxAmount").queryList();
if (UtilValidate.isNotEmpty(billingAccountId)) {
paymentPrefsBa = EntityQuery.use(delegator).from("OrderPaymentPreference").where("orderId", orderId, "paymentMethodTypeId", "EXT_BILLACT", "statusId", "PAYMENT_NOT_RECEIVED").orderBy("-maxAmount").queryList();
}
} catch (GenericEntityException gee) {
Debug.logError(gee, "Problems getting entity record(s), see stack trace", module);
return ServiceUtil.returnError(UtilProperties.getMessage(resourceOrder, "OrderOrderNotFound", UtilMisc.toMap("orderId", orderId), locale) + " " + gee.toString());
}
// error if no order was found
if (orderHeader == null) {
return ServiceUtil.returnError(UtilProperties.getMessage(resourceOrder, "OrderOrderNotFound", UtilMisc.toMap("orderId", orderId), locale));
}
// Check if the outstanding amount for the order is greater than the
// amount that we are going to capture.
OrderReadHelper orh = new OrderReadHelper(orderHeader);
BigDecimal orderGrandTotal = orh.getOrderGrandTotal();
orderGrandTotal = orderGrandTotal.setScale(decimals, rounding);
BigDecimal totalPayments = PaymentWorker.getPaymentsTotal(orh.getOrderPayments());
totalPayments = totalPayments.setScale(decimals, rounding);
BigDecimal remainingTotal = orderGrandTotal.subtract(totalPayments);
if (Debug.infoOn()) {
Debug.logInfo("The Remaining Total for order: " + orderId + " is: " + remainingTotal, module);
}
// The amount to capture cannot be greater than the remaining total
amountToCapture = amountToCapture.min(remainingTotal);
if (Debug.infoOn()) {
Debug.logInfo("Actual Expected Capture Amount : " + amountToCapture, module);
}
// Process billing accounts payments
if (UtilValidate.isNotEmpty(paymentPrefsBa)) {
Iterator<GenericValue> paymentsBa = paymentPrefsBa.iterator();
while (paymentsBa.hasNext()) {
GenericValue paymentPref = paymentsBa.next();
BigDecimal authAmount = paymentPref.getBigDecimal("maxAmount");
if (authAmount == null) {
authAmount = ZERO;
}
authAmount = authAmount.setScale(decimals, rounding);
if (authAmount.compareTo(ZERO) == 0) {
// nothing to capture
Debug.logInfo("Nothing to capture; authAmount = 0", module);
continue;
}
// the amount for *this* capture
BigDecimal amountThisCapture = amountToCapture.min(authAmount);
// decrease amount of next payment preference to capture
amountToCapture = amountToCapture.subtract(amountThisCapture);
// to the billing account and we apply them to the invoice
if (UtilValidate.isNotEmpty(invoiceId)) {
Map<String, Object> captureResult = null;
try {
captureResult = dispatcher.runSync("captureBillingAccountPayments", UtilMisc.<String, Object>toMap("invoiceId", invoiceId, "billingAccountId", billingAccountId, "captureAmount", amountThisCapture, "orderId", orderId, "userLogin", userLogin));
if (ServiceUtil.isError(captureResult)) {
return ServiceUtil.returnError(ServiceUtil.getErrorMessage(captureResult));
}
} catch (GenericServiceException ex) {
return ServiceUtil.returnError(ex.getMessage());
}
if (captureResult != null) {
BigDecimal amountCaptured = (BigDecimal) captureResult.get("captureAmount");
if (Debug.infoOn()) {
Debug.logInfo("Amount captured for order [" + orderId + "] from unapplied payments associated to billing account [" + billingAccountId + "] is: " + amountCaptured, module);
}
amountCaptured = amountCaptured.setScale(decimals, rounding);
if (amountCaptured.compareTo(BigDecimal.ZERO) == 0) {
continue;
}
// add the invoiceId to the result for processing
captureResult.put("invoiceId", invoiceId);
captureResult.put("captureResult", Boolean.TRUE);
captureResult.put("orderPaymentPreference", paymentPref);
if (context.get("captureRefNum") == null) {
// FIXME: this is an hack to avoid a service validation error for processCaptureResult (captureRefNum is mandatory, but it is not used for billing accounts)
captureResult.put("captureRefNum", "");
}
// process the capture's results
try {
// the following method will set on the OrderPaymentPreference:
// maxAmount = amountCaptured and
// statusId = PAYMENT_RECEIVED
processResult(dctx, captureResult, userLogin, paymentPref, locale);
} catch (GeneralException e) {
Debug.logError(e, "Trouble processing the result; captureResult: " + captureResult, module);
return ServiceUtil.returnError(UtilProperties.getMessage(resourceOrder, "AccountingPaymentCannotBeCaptured", locale) + " " + captureResult);
}
// create any splits which are needed
if (authAmount.compareTo(amountCaptured) > 0) {
BigDecimal splitAmount = authAmount.subtract(amountCaptured);
try {
Map<String, Object> splitCtx = UtilMisc.<String, Object>toMap("userLogin", userLogin, "orderPaymentPreference", paymentPref, "splitAmount", splitAmount);
dispatcher.addCommitService("processCaptureSplitPayment", splitCtx, true);
} catch (GenericServiceException e) {
Debug.logWarning(e, "Problem processing the capture split payment", module);
}
if (Debug.infoOn()) {
Debug.logInfo("Captured: " + amountThisCapture + " Remaining (re-auth): " + splitAmount, module);
}
}
} else {
Debug.logError("Payment not captured for order [" + orderId + "] from billing account [" + billingAccountId + "]", module);
}
}
}
}
// iterate over the prefs and capture each one until we meet our total
if (UtilValidate.isNotEmpty(paymentPrefs)) {
Iterator<GenericValue> payments = paymentPrefs.iterator();
while (payments.hasNext()) {
// DEJ20060708: Do we really want to just log and ignore the errors like this? I've improved a few of these in a review today, but it is being done all over...
GenericValue paymentPref = payments.next();
GenericValue authTrans = getAuthTransaction(paymentPref);
if (authTrans == null) {
Debug.logWarning("Authorized OrderPaymentPreference has no corresponding PaymentGatewayResponse, cannot capture payment: " + paymentPref, module);
continue;
}
// check for an existing capture
GenericValue captureTrans = getCaptureTransaction(paymentPref);
if (captureTrans != null) {
Debug.logWarning("Attempt to capture and already captured preference: " + captureTrans, module);
continue;
}
BigDecimal authAmount = authTrans.getBigDecimal("amount");
if (authAmount == null) {
authAmount = ZERO;
}
authAmount = authAmount.setScale(decimals, rounding);
if (authAmount.compareTo(ZERO) == 0) {
// nothing to capture
Debug.logInfo("Nothing to capture; authAmount = 0", module);
continue;
}
// the amount for *this* capture
BigDecimal amountThisCapture;
// determine how much for *this* capture
if (isReplacementOrder(orderHeader)) {
// if it is a replacement order then just capture the auth amount
amountThisCapture = authAmount;
} else if (authAmount.compareTo(amountToCapture) >= 0) {
// if the auth amount is more then expected capture just capture what is expected
amountThisCapture = amountToCapture;
} else if (payments.hasNext()) {
// if we have more payments to capture; just capture what was authorized
amountThisCapture = authAmount;
} else {
// we need to capture more then what was authorized; re-auth for the new amount
// TODO: add what the billing account cannot support to the re-auth amount
// TODO: add support for re-auth for additional funds
// just in case; we will capture the authorized amount here; until this is implemented
Debug.logError("The amount to capture was more then what was authorized; we only captured the authorized amount : " + paymentPref, module);
amountThisCapture = authAmount;
}
Map<String, Object> captureResult = capturePayment(dctx, userLogin, orh, paymentPref, amountThisCapture, locale);
if (captureResult != null && ServiceUtil.isSuccess(captureResult)) {
// credit card processors return captureAmount, but gift certificate processors return processAmount
BigDecimal amountCaptured = (BigDecimal) captureResult.get("captureAmount");
if (amountCaptured == null) {
amountCaptured = (BigDecimal) captureResult.get("processAmount");
}
amountCaptured = amountCaptured.setScale(decimals, rounding);
// decrease amount of next payment preference to capture
amountToCapture = amountToCapture.subtract(amountCaptured);
// add the invoiceId to the result for processing, not for a replacement order
if (!isReplacementOrder(orderHeader)) {
captureResult.put("invoiceId", invoiceId);
}
// process the capture's results
try {
processResult(dctx, captureResult, userLogin, paymentPref, locale);
} catch (GeneralException e) {
Debug.logError(e, "Trouble processing the result; captureResult: " + captureResult, module);
return ServiceUtil.returnError(UtilProperties.getMessage(resourceOrder, "AccountingPaymentCannotBeCaptured", locale) + " " + captureResult);
}
// create any splits which are needed
if (authAmount.compareTo(amountCaptured) > 0) {
BigDecimal splitAmount = authAmount.subtract(amountCaptured);
try {
Map<String, Object> splitCtx = UtilMisc.<String, Object>toMap("userLogin", userLogin, "orderPaymentPreference", paymentPref, "splitAmount", splitAmount);
dispatcher.addCommitService("processCaptureSplitPayment", splitCtx, true);
} catch (GenericServiceException e) {
Debug.logWarning(e, "Problem processing the capture split payment", module);
}
if (Debug.infoOn()) {
Debug.logInfo("Captured: " + amountThisCapture + " Remaining (re-auth): " + splitAmount, module);
}
}
} else {
Debug.logError("Payment not captured", module);
}
}
}
if (amountToCapture.compareTo(ZERO) > 0) {
GenericValue productStore = orh.getProductStore();
if (UtilValidate.isNotEmpty(productStore)) {
boolean shipIfCaptureFails = UtilValidate.isEmpty(productStore.get("shipIfCaptureFails")) || "Y".equalsIgnoreCase(productStore.getString("shipIfCaptureFails"));
if (!shipIfCaptureFails) {
return ServiceUtil.returnError(UtilProperties.getMessage(resourceOrder, "AccountingPaymentCannotBeCaptured", locale));
} else {
Debug.logWarning("Payment capture failed, shipping order anyway as per ProductStore setting (shipIfCaptureFails)", module);
}
}
Map<String, Object> result = ServiceUtil.returnSuccess();
result.put("processResult", "FAILED");
return result;
} else {
Map<String, Object> result = ServiceUtil.returnSuccess();
result.put("processResult", "COMPLETE");
return result;
}
}
use of org.apache.ofbiz.base.util.GeneralException in project ofbiz-framework by apache.
the class PaymentGatewayServices method processAuthResult.
private static void processAuthResult(DispatchContext dctx, Map<String, Object> result, GenericValue userLogin, GenericValue paymentPreference) throws GeneralException {
LocalDispatcher dispatcher = dctx.getDispatcher();
result.put("userLogin", userLogin);
result.put("orderPaymentPreference", paymentPreference);
ModelService model = dctx.getModelService("processAuthResult");
Map<String, Object> context = model.makeValid(result, ModelService.IN_PARAM);
// in case we rollback make sure this service gets called
dispatcher.addRollbackService(model.name, context, true);
// invoke the service
Map<String, Object> resResp;
try {
resResp = dispatcher.runSync(model.name, context);
} catch (GenericServiceException e) {
Debug.logError(e, module);
throw e;
}
if (ServiceUtil.isError(resResp)) {
throw new GeneralException(ServiceUtil.getErrorMessage(resResp));
}
}
use of org.apache.ofbiz.base.util.GeneralException in project ofbiz-framework by apache.
the class PaymentGatewayServices method processReAuthFromCaptureFailure.
private static void processReAuthFromCaptureFailure(DispatchContext dctx, Map<String, Object> result, BigDecimal amount, GenericValue userLogin, GenericValue paymentPreference, Locale locale) throws GeneralException {
LocalDispatcher dispatcher = dctx.getDispatcher();
// lookup the order header
OrderReadHelper orh = null;
try {
GenericValue orderHeader = paymentPreference.getRelatedOne("OrderHeader", false);
if (orderHeader != null) {
orh = new OrderReadHelper(orderHeader);
}
} catch (GenericEntityException e) {
throw new GeneralException("Problems getting OrderHeader; cannot re-auth the payment", e);
}
// make sure the order exists
if (orh == null) {
throw new GeneralException("No order found for payment preference #" + paymentPreference.get("orderPaymentPreferenceId"));
}
// set the re-auth amount
if (amount == null) {
amount = ZERO;
}
if (amount.compareTo(ZERO) == 0) {
amount = paymentPreference.getBigDecimal("maxAmount");
Debug.logInfo("resetting payment amount from 0.00 to correctMax amount", module);
}
Debug.logInfo("reauth with amount: " + amount, module);
// first re-auth the card
Map<String, Object> authPayRes = authPayment(dispatcher, userLogin, orh, paymentPreference, amount, true, null);
if (authPayRes == null) {
throw new GeneralException("Null result returned from payment re-authorization");
}
// check the auth-response
Boolean authResp = (Boolean) authPayRes.get("authResult");
Boolean capResp = (Boolean) authPayRes.get("captureResult");
if (authResp != null && Boolean.TRUE.equals(authResp)) {
GenericValue authTrans = processAuthRetryResult(dctx, authPayRes, userLogin, paymentPreference);
// check if auto-capture was enabled; process if so
if (capResp != null && capResp.booleanValue()) {
processCaptureResult(dctx, result, userLogin, paymentPreference, locale);
} else {
// no auto-capture; do manual capture now
Map<String, Object> capPayRes = capturePayment(dctx, userLogin, orh, paymentPreference, amount, authTrans, locale);
if (capPayRes == null) {
throw new GeneralException("Problems trying to capture payment (null result)");
}
// process the capture result
Boolean capPayResp = (Boolean) capPayRes.get("captureResult");
if (capPayResp != null && capPayResp.booleanValue()) {
// process the capture result
processCaptureResult(dctx, capPayRes, userLogin, paymentPreference, locale);
} else {
throw new GeneralException("Capture of authorized payment failed");
}
}
} else {
throw new GeneralException("Payment re-authorization failed");
}
}
use of org.apache.ofbiz.base.util.GeneralException in project ofbiz-framework by apache.
the class PaymentGatewayServices method authPayment.
private static Map<String, Object> authPayment(LocalDispatcher dispatcher, GenericValue userLogin, OrderReadHelper orh, GenericValue paymentPreference, BigDecimal totalRemaining, boolean reauth, BigDecimal overrideAmount) throws GeneralException {
String paymentConfig = null;
String serviceName = null;
String paymentGatewayConfigId = null;
// get the payment settings i.e. serviceName and config properties file name
String serviceType = AUTH_SERVICE_TYPE;
if (reauth) {
serviceType = REAUTH_SERVICE_TYPE;
}
GenericValue paymentSettings = getPaymentSettings(orh.getOrderHeader(), paymentPreference, serviceType, false);
if (paymentSettings != null) {
String customMethodId = paymentSettings.getString("paymentCustomMethodId");
if (UtilValidate.isNotEmpty(customMethodId)) {
serviceName = getPaymentCustomMethod(orh.getOrderHeader().getDelegator(), customMethodId);
}
if (UtilValidate.isEmpty(serviceName)) {
serviceName = paymentSettings.getString("paymentService");
}
paymentConfig = paymentSettings.getString("paymentPropertiesPath");
paymentGatewayConfigId = paymentSettings.getString("paymentGatewayConfigId");
} else {
throw new GeneralException("Could not find any valid payment settings for order with ID [" + orh.getOrderId() + "], and payment operation (serviceType) [" + serviceType + "]");
}
// make sure the service name is not null
if (serviceName == null) {
throw new GeneralException("Invalid payment processor, serviceName is null: " + paymentSettings);
}
// make the process context
Map<String, Object> processContext = new HashMap<>();
// get the visit record to obtain the client's IP address
GenericValue orderHeader = orh.getOrderHeader();
String visitId = orderHeader.getString("visitId");
GenericValue visit = null;
if (visitId != null) {
try {
visit = orderHeader.getDelegator().findOne("Visit", UtilMisc.toMap("visitId", visitId), false);
} catch (GenericEntityException e) {
Debug.logError(e, module);
}
}
if (visit != null && visit.get("clientIpAddress") != null) {
processContext.put("customerIpAddress", visit.getString("clientIpAddress"));
}
GenericValue productStore = orderHeader.getRelatedOne("ProductStore", false);
processContext.put("userLogin", userLogin);
processContext.put("orderId", orh.getOrderId());
processContext.put("orderItems", orh.getOrderItems());
// TODO refactor the payment API to handle support all addresses
processContext.put("shippingAddress", EntityUtil.getFirst(orh.getShippingLocations()));
processContext.put("paymentConfig", paymentConfig);
processContext.put("paymentGatewayConfigId", paymentGatewayConfigId);
processContext.put("currency", orh.getCurrency());
processContext.put("orderPaymentPreference", paymentPreference);
if (paymentPreference.get("securityCode") != null) {
processContext.put("cardSecurityCode", paymentPreference.get("securityCode"));
}
// get the billing information
getBillingInformation(orh, paymentPreference, processContext);
// default charge is totalRemaining
BigDecimal processAmount = totalRemaining;
// use override or max amount available
if (overrideAmount != null) {
processAmount = overrideAmount;
} else if (paymentPreference.get("maxAmount") != null) {
processAmount = paymentPreference.getBigDecimal("maxAmount");
}
// Check if the order is a replacement order
boolean replacementOrderFlag = isReplacementOrder(orderHeader);
// don't authorized more then what is required
if (!replacementOrderFlag && processAmount.compareTo(totalRemaining) > 0) {
processAmount = totalRemaining;
}
// format the decimal
processAmount = processAmount.setScale(decimals, rounding);
if (Debug.verboseOn()) {
Debug.logVerbose("Charging amount: " + processAmount, module);
}
processContext.put("processAmount", processAmount);
// invoke the processor
Map<String, Object> processorResult = null;
try {
// invoke the payment processor; allow 5 minute transaction timeout and require a new tx; we'll capture the error and pass back nicely
GenericValue creditCard = (GenericValue) processContext.get("creditCard");
// only try other exp dates if orderHeader.autoOrderShoppingListId is not empty, productStore.autoOrderCcTryExp=Y and this payment is a creditCard
boolean tryOtherExpDates = "Y".equals(productStore.getString("autoOrderCcTryExp")) && creditCard != null && UtilValidate.isNotEmpty(orderHeader.getString("autoOrderShoppingListId"));
// if we are not trying other expire dates OR if we are and the date is after today, then run the service
if (!tryOtherExpDates || UtilValidate.isDateAfterToday(creditCard.getString("expireDate"))) {
processorResult = dispatcher.runSync(serviceName, processContext, TX_TIME, true);
if (ServiceUtil.isError(processorResult)) {
return ServiceUtil.returnError(ServiceUtil.getErrorMessage(processorResult));
}
}
// try other expire dates if the expireDate is not after today, or if we called the auth service and resultBadExpire = true
if (tryOtherExpDates && (!UtilValidate.isDateAfterToday(creditCard.getString("expireDate")) || (processorResult != null && Boolean.TRUE.equals(processorResult.get("resultBadExpire"))))) {
// try adding 2, 3, 4 years later with the same month
String expireDate = creditCard.getString("expireDate");
int dateSlash1 = expireDate.indexOf("/");
String month = expireDate.substring(0, dateSlash1);
String year = expireDate.substring(dateSlash1 + 1);
// start adding 2 years, if comes back with resultBadExpire try again up to twice incrementing one year
year = StringUtil.addToNumberString(year, 2);
// note that this is set in memory only for now, not saved to the database unless successful
creditCard.set("expireDate", month + "/" + year);
// don't need to set back in the processContext, it's already there: processContext.put("creditCard", creditCard);
processorResult = dispatcher.runSync(serviceName, processContext, TX_TIME, true);
if (ServiceUtil.isError(processorResult)) {
return ServiceUtil.returnError(ServiceUtil.getErrorMessage(processorResult));
}
// note that these additional tries will only be done if the service return is not an error, in that case we let it pass through to the normal error handling
if (ServiceUtil.isSuccess(processorResult) && Boolean.TRUE.equals(processorResult.get("resultBadExpire"))) {
// okay, try one more year...
year = StringUtil.addToNumberString(year, 1);
creditCard.set("expireDate", month + "/" + year);
processorResult = dispatcher.runSync(serviceName, processContext, TX_TIME, true);
if (ServiceUtil.isError(processorResult)) {
return ServiceUtil.returnError(ServiceUtil.getErrorMessage(processorResult));
}
}
if (ServiceUtil.isSuccess(processorResult) && Boolean.TRUE.equals(processorResult.get("resultBadExpire"))) {
// okay, try one more year... and this is the last try
year = StringUtil.addToNumberString(year, 1);
creditCard.set("expireDate", month + "/" + year);
processorResult = dispatcher.runSync(serviceName, processContext, TX_TIME, true);
if (ServiceUtil.isError(processorResult)) {
return ServiceUtil.returnError(ServiceUtil.getErrorMessage(processorResult));
}
}
// at this point if we have a successful result, let's save the new creditCard expireDate
if (ServiceUtil.isSuccess(processorResult) && Boolean.TRUE.equals(processorResult.get("authResult"))) {
// TODO: this is bad; we should be expiring the old card and creating a new one instead of editing it
creditCard.store();
}
}
} catch (GenericServiceException e) {
Debug.logError(e, "Error occurred on: " + serviceName + ", Order ID is: [" + orh.getOrderId() + "]", module);
throw new GeneralException("Problems invoking payment processor! Will retry later. Order ID is: [" + orh.getOrderId() + "]", e);
}
if (processorResult != null) {
// check for errors from the processor implementation
if (ServiceUtil.isError(processorResult)) {
Debug.logError("Processor failed; will retry later: " + processorResult.get(ModelService.ERROR_MESSAGE), module);
// log the error message as a gateway response when it fails
saveError(dispatcher, userLogin, paymentPreference, processorResult, AUTH_SERVICE_TYPE, "PGT_AUTHORIZE");
// this is the one place where we want to return null because the calling method will look for this
return null;
}
// pass the payTo partyId to the result processor; we just add it to the result context.
String payToPartyId = getPayToPartyId(orh.getOrderHeader());
processorResult.put("payToPartyId", payToPartyId);
// add paymentSettings to result; for use by later processors
processorResult.put("paymentSettings", paymentSettings);
// and pass on the currencyUomId
processorResult.put("currencyUomId", orh.getCurrency());
}
return processorResult;
}
Aggregations