use of org.apache.ofbiz.service.GenericServiceException in project ofbiz-framework by apache.
the class PaymentGatewayServices method savePgrAndMsgs.
private static void savePgrAndMsgs(DispatchContext dctx, GenericValue pgr, List<GenericValue> messages) {
Map<String, GenericValue> context = UtilMisc.<String, GenericValue>toMap("paymentGatewayResponse", pgr, "messages", messages);
LocalDispatcher dispatcher = dctx.getDispatcher();
Delegator delegator = dctx.getDelegator();
try {
dispatcher.addRollbackService("savePaymentGatewayResponseAndMessages", context, true);
delegator.create(pgr);
for (GenericValue message : messages) {
delegator.create(message);
}
} catch (GenericEntityException | GenericServiceException ge) {
Debug.logError(ge, module);
} catch (Exception e) {
Debug.logError(e, module);
}
}
use of org.apache.ofbiz.service.GenericServiceException 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.service.GenericServiceException in project ofbiz-framework by apache.
the class PaymentGatewayServices method releaseOrderPaymentPreference.
/**
* Releases authorization for a single OrderPaymentPreference through service calls to the defined processing service for the ProductStore/PaymentMethodType
* @return SUCCESS|FAILED|ERROR for complete processing of payment.
*/
public static Map<String, Object> releaseOrderPaymentPreference(DispatchContext dctx, Map<String, ? extends Object> context) {
Delegator delegator = dctx.getDelegator();
LocalDispatcher dispatcher = dctx.getDispatcher();
GenericValue userLogin = (GenericValue) context.get("userLogin");
String orderPaymentPreferenceId = (String) context.get("orderPaymentPreferenceId");
Locale locale = (Locale) context.get("locale");
Map<String, Object> result = ServiceUtil.returnSuccess();
// Get the OrderPaymentPreference
GenericValue paymentPref = null;
try {
paymentPref = EntityQuery.use(delegator).from("OrderPaymentPreference").where("orderPaymentPreferenceId", orderPaymentPreferenceId).queryOne();
} catch (GenericEntityException e) {
Debug.logWarning(e, "Problem getting OrderPaymentPreference for orderPaymentPreferenceId " + orderPaymentPreferenceId, module);
return ServiceUtil.returnError(UtilProperties.getMessage(resource, "AccountingProblemGettingOrderPaymentPreferences", locale) + " " + orderPaymentPreferenceId);
}
// Error if no OrderPaymentPreference was found
if (paymentPref == null) {
Debug.logWarning("Could not find OrderPaymentPreference with orderPaymentPreferenceId: " + orderPaymentPreferenceId, module);
return ServiceUtil.returnError(UtilProperties.getMessage(resource, "AccountingProblemGettingOrderPaymentPreferences", locale) + " " + orderPaymentPreferenceId);
}
// Get the OrderHeader
GenericValue orderHeader = null;
String orderId = paymentPref.getString("orderId");
try {
orderHeader = EntityQuery.use(delegator).from("OrderHeader").where("orderId", orderId).queryOne();
} catch (GenericEntityException e) {
Debug.logWarning(e, "Problem getting OrderHeader for orderId " + orderId, module);
return ServiceUtil.returnError(UtilProperties.getMessage(resourceOrder, "OrderOrderNotFound", UtilMisc.toMap("orderId", orderId), locale));
}
// Error if no OrderHeader was found
if (orderHeader == null) {
Debug.logWarning("Could not find OrderHeader with orderId: " + orderId + "; not processing payments.", module);
return ServiceUtil.returnError(UtilProperties.getMessage(resourceOrder, "OrderOrderNotFound", UtilMisc.toMap("orderId", orderId), locale));
}
OrderReadHelper orh = new OrderReadHelper(orderHeader);
String currency = orh.getCurrency();
// look up the payment configuration settings
String serviceName = null;
String paymentConfig = null;
String paymentGatewayConfigId = null;
// get the payment settings i.e. serviceName and config properties file name
GenericValue paymentSettings = getPaymentSettings(orderHeader, paymentPref, RELEASE_SERVICE_TYPE, 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");
if (serviceName == null) {
Debug.logWarning("No payment release service for - " + paymentPref.getString("paymentMethodTypeId"), module);
return ServiceUtil.returnError(UtilProperties.getMessage(resourceOrder, "AccountingTroubleCallingReleaseOrderPaymentPreferenceService", locale) + " " + paymentPref.getString("paymentMethodTypeId"));
}
} else {
Debug.logWarning("No payment release settings found for - " + paymentPref.getString("paymentMethodTypeId"), module);
return ServiceUtil.returnError(UtilProperties.getMessage(resourceOrder, "AccountingTroubleCallingReleaseOrderPaymentPreferenceService", locale) + " " + paymentPref.getString("paymentMethodTypeId"));
}
if (UtilValidate.isEmpty(paymentConfig)) {
paymentConfig = "payment.properties";
}
GenericValue authTransaction = PaymentGatewayServices.getAuthTransaction(paymentPref);
Map<String, Object> releaseContext = new HashMap<>();
releaseContext.put("orderPaymentPreference", paymentPref);
releaseContext.put("releaseAmount", authTransaction.getBigDecimal("amount"));
releaseContext.put("currency", currency);
releaseContext.put("paymentConfig", paymentConfig);
releaseContext.put("paymentGatewayConfigId", paymentGatewayConfigId);
releaseContext.put("userLogin", userLogin);
// run the defined service
Map<String, Object> releaseResult = null;
try {
releaseResult = dispatcher.runSync(serviceName, releaseContext, TX_TIME, true);
} catch (GenericServiceException e) {
Debug.logError(e, "Problem releasing payment", module);
return ServiceUtil.returnError(UtilProperties.getMessage(resourceOrder, "AccountingTroubleCallingReleaseOrderPaymentPreferenceService", locale));
}
// get the release result code
if (releaseResult != null && ServiceUtil.isSuccess(releaseResult)) {
Map<String, Object> releaseResRes;
try {
ModelService model = dctx.getModelService("processReleaseResult");
releaseResult.put("orderPaymentPreference", paymentPref);
releaseResult.put("userLogin", userLogin);
Map<String, Object> resCtx = model.makeValid(releaseResult, ModelService.IN_PARAM);
releaseResRes = dispatcher.runSync(model.name, resCtx);
} catch (GenericServiceException e) {
Debug.logError(e, "Trouble processing the release results", module);
return ServiceUtil.returnError(UtilProperties.getMessage(resourceOrder, "AccountingTroubleCallingReleaseOrderPaymentPreferenceService", locale) + " " + e.getMessage());
}
if (releaseResRes != null && ServiceUtil.isError(releaseResRes)) {
return ServiceUtil.returnError(ServiceUtil.getErrorMessage(releaseResRes));
}
} else if (ServiceUtil.isError(releaseResult)) {
saveError(dispatcher, userLogin, paymentPref, releaseResult, RELEASE_SERVICE_TYPE, "PGT_RELEASE");
result = ServiceUtil.returnError(ServiceUtil.getErrorMessage(releaseResult));
}
return result;
}
use of org.apache.ofbiz.service.GenericServiceException in project ofbiz-framework by apache.
the class PaymentGatewayServices method retryFailedOrderAuth.
public static Map<String, Object> retryFailedOrderAuth(DispatchContext dctx, Map<String, ? extends Object> context) {
Delegator delegator = dctx.getDelegator();
LocalDispatcher dispatcher = dctx.getDispatcher();
String orderId = (String) context.get("orderId");
GenericValue userLogin = (GenericValue) context.get("userLogin");
Locale locale = (Locale) context.get("locale");
// get the order header
GenericValue orderHeader = null;
try {
orderHeader = EntityQuery.use(delegator).from("OrderHeader").where("orderId", orderId).queryOne();
} catch (GenericEntityException e) {
Debug.logError(e, module);
return ServiceUtil.returnError(e.toString());
}
// make sure we have a valid order record
if (orderHeader == null || orderHeader.get("statusId") == null) {
return ServiceUtil.returnError(UtilProperties.getMessage(resourceOrder, "OrderOrderNotFound", UtilMisc.toMap("orderId", orderId), locale));
}
// check the current order status
if (!"ORDER_CREATED".equals(orderHeader.getString("statusId"))) {
// if we are out of the created status; then we were either cancelled, rejected or approved
Debug.logWarning("Was re-trying a failed auth for orderId [" + orderId + "] but it is not in the ORDER_CREATED status, so skipping.", module);
return ServiceUtil.returnSuccess();
}
// run the auth service and check for failure(s)
Map<String, Object> serviceResult = null;
try {
serviceResult = dispatcher.runSync("authOrderPayments", UtilMisc.<String, Object>toMap("orderId", orderId, "userLogin", userLogin));
} catch (GenericServiceException e) {
Debug.logError(e, module);
return ServiceUtil.returnError(e.toString());
}
if (ServiceUtil.isError(serviceResult)) {
return ServiceUtil.returnError(ServiceUtil.getErrorMessage(serviceResult));
}
// check to see if there was a processor failure
String authResp = (String) serviceResult.get("processResult");
if (authResp == null) {
authResp = "ERROR";
}
if ("ERROR".equals(authResp)) {
Debug.logWarning("The payment processor had a failure in processing, will not modify any status", module);
} else {
if ("FAILED".equals(authResp)) {
// declined; update the order status
OrderChangeHelper.rejectOrder(dispatcher, userLogin, orderId);
} else if ("APPROVED".equals(authResp)) {
// approved; update the order status
OrderChangeHelper.approveOrder(dispatcher, userLogin, orderId);
}
}
Map<String, Object> result = ServiceUtil.returnSuccess();
result.put("processResult", authResp);
return result;
}
use of org.apache.ofbiz.service.GenericServiceException 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));
}
}
Aggregations