use of org.apache.ofbiz.service.LocalDispatcher 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.service.LocalDispatcher in project ofbiz-framework by apache.
the class PaymentGatewayServices method processReleaseResult.
public static Map<String, Object> processReleaseResult(DispatchContext dctx, Map<String, ? extends Object> context) {
Delegator delegator = dctx.getDelegator();
LocalDispatcher dispatcher = dctx.getDispatcher();
GenericValue userLogin = (GenericValue) context.get("userLogin");
String currencyUomId = (String) context.get("currencyUomId");
GenericValue paymentPref = (GenericValue) context.get("orderPaymentPreference");
Boolean releaseResponse = (Boolean) context.get("releaseResult");
Locale locale = (Locale) context.get("locale");
// create the PaymentGatewayResponse
String responseId = delegator.getNextSeqId("PaymentGatewayResponse");
GenericValue pgResponse = delegator.makeValue("PaymentGatewayResponse");
pgResponse.set("paymentGatewayResponseId", responseId);
pgResponse.set("paymentServiceTypeEnumId", RELEASE_SERVICE_TYPE);
pgResponse.set("orderPaymentPreferenceId", paymentPref.get("orderPaymentPreferenceId"));
pgResponse.set("paymentMethodTypeId", paymentPref.get("paymentMethodTypeId"));
pgResponse.set("paymentMethodId", paymentPref.get("paymentMethodId"));
pgResponse.set("transCodeEnumId", "PGT_RELEASE");
// set the release info
pgResponse.set("amount", context.get("releaseAmount"));
pgResponse.set("referenceNum", context.get("releaseRefNum"));
pgResponse.set("altReference", context.get("releaseAltRefNum"));
pgResponse.set("gatewayCode", context.get("releaseCode"));
pgResponse.set("gatewayFlag", context.get("releaseFlag"));
pgResponse.set("gatewayMessage", context.get("releaseMessage"));
pgResponse.set("transactionDate", UtilDateTime.nowTimestamp());
pgResponse.set("currencyUomId", currencyUomId);
// store the gateway response
savePgr(dctx, pgResponse);
// create the internal messages
List<String> messages = UtilGenerics.cast(context.get("internalRespMsgs"));
if (UtilValidate.isNotEmpty(messages)) {
Iterator<String> i = messages.iterator();
while (i.hasNext()) {
GenericValue respMsg = delegator.makeValue("PaymentGatewayRespMsg");
String respMsgId = delegator.getNextSeqId("PaymentGatewayRespMsg");
String message = i.next();
respMsg.set("paymentGatewayRespMsgId", respMsgId);
respMsg.set("paymentGatewayResponseId", responseId);
respMsg.set("pgrMessage", message);
// store the messages
savePgr(dctx, respMsg);
}
}
if (releaseResponse != null && releaseResponse.booleanValue()) {
paymentPref.set("statusId", "PAYMENT_CANCELLED");
try {
paymentPref.store();
} catch (GenericEntityException e) {
Debug.logError(e, "Problem storing updated payment preference; authorization was released!", module);
}
// cancel any payment records
List<GenericValue> paymentList = null;
try {
paymentList = paymentPref.getRelated("Payment", null, null, false);
} catch (GenericEntityException e) {
Debug.logError(e, "Unable to get Payment records from OrderPaymentPreference : " + paymentPref, module);
}
if (paymentList != null) {
Iterator<GenericValue> pi = paymentList.iterator();
while (pi.hasNext()) {
GenericValue pay = pi.next();
try {
Map<String, Object> cancelResults = dispatcher.runSync("setPaymentStatus", UtilMisc.toMap("userLogin", userLogin, "paymentId", pay.get("paymentId"), "statusId", "PMNT_CANCELLED"));
if (ServiceUtil.isError(cancelResults)) {
throw new GenericServiceException(ServiceUtil.getErrorMessage(cancelResults));
}
} catch (GenericServiceException e) {
Debug.logError(e, "Unable to cancel Payment : " + pay, module);
}
}
}
} else {
Debug.logError("Release failed for pref : " + paymentPref, module);
return ServiceUtil.returnFailure(UtilProperties.getMessage(resourceOrder, "AccountingTroubleCallingReleaseOrderPaymentPreferenceService", locale) + " " + paymentPref);
}
return ServiceUtil.returnSuccess();
}
use of org.apache.ofbiz.service.LocalDispatcher in project ofbiz-framework by apache.
the class PaymentGatewayServices method authOrderPaymentPreference.
/**
* Authorizes a single order preference with an option to specify an amount. The result map has the Booleans
* "errors" and "finished" which notify the user if there were any errors and if the authorization was finished.
* There is also a List "messages" for the authorization response messages and a BigDecimal, "processAmount" as the
* amount processed.
*
* TODO: it might be nice to return the paymentGatewayResponseId
*/
public static Map<String, Object> authOrderPaymentPreference(DispatchContext dctx, Map<String, ? extends Object> context) {
Delegator delegator = dctx.getDelegator();
LocalDispatcher dispatcher = dctx.getDispatcher();
GenericValue userLogin = (GenericValue) context.get("userLogin");
Locale locale = (Locale) context.get("locale");
String orderPaymentPreferenceId = (String) context.get("orderPaymentPreferenceId");
BigDecimal overrideAmount = (BigDecimal) context.get("overrideAmount");
// validate overrideAmount if its available
if (overrideAmount != null) {
if (overrideAmount.compareTo(BigDecimal.ZERO) < 0) {
return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "AccountingPaymentAmountIsNegative", UtilMisc.toMap("overrideAmount", overrideAmount), locale));
}
if (overrideAmount.compareTo(BigDecimal.ZERO) == 0) {
return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "AccountingPaymentAmountIsZero", UtilMisc.toMap("overrideAmount", overrideAmount), locale));
}
}
GenericValue orderHeader = null;
GenericValue orderPaymentPreference = null;
try {
orderPaymentPreference = EntityQuery.use(delegator).from("OrderPaymentPreference").where("orderPaymentPreferenceId", orderPaymentPreferenceId).queryOne();
orderHeader = orderPaymentPreference.getRelatedOne("OrderHeader", false);
} catch (GenericEntityException e) {
Debug.logError(e, module);
return ServiceUtil.returnError(UtilProperties.getMessage(resource, "AccountingProblemGettingOrderPaymentPreferences", locale) + " " + orderPaymentPreferenceId);
}
OrderReadHelper orh = new OrderReadHelper(orderHeader);
// get the total remaining
BigDecimal totalRemaining = orh.getOrderGrandTotal();
// get the process attempts so far
Long procAttempt = orderPaymentPreference.getLong("processAttempt");
if (procAttempt == null) {
procAttempt = Long.valueOf(0);
}
// update the process attempt count
orderPaymentPreference.set("processAttempt", Long.valueOf(procAttempt.longValue() + 1));
try {
orderPaymentPreference.store();
orderPaymentPreference.refresh();
} catch (GenericEntityException e) {
Debug.logError(e, module);
return ServiceUtil.returnError(UtilProperties.getMessage(resource, "AccountingProblemGettingOrderPaymentPreferences", locale));
}
// if we are already authorized, then this is a re-auth request
boolean reAuth = false;
if (orderPaymentPreference.get("statusId") != null && "PAYMENT_AUTHORIZED".equals(orderPaymentPreference.getString("statusId"))) {
reAuth = true;
}
// use overrideAmount or maxAmount
BigDecimal transAmount = null;
if (overrideAmount != null) {
transAmount = overrideAmount;
} else {
transAmount = orderPaymentPreference.getBigDecimal("maxAmount");
}
// round this before moving on just in case a funny number made it this far
transAmount = transAmount.setScale(decimals, rounding);
// if our transaction amount exists and is zero, there's nothing to process, so return
if ((transAmount != null) && (transAmount.compareTo(BigDecimal.ZERO) <= 0)) {
Map<String, Object> results = ServiceUtil.returnSuccess();
// finished is true since there is nothing to do
results.put("finished", Boolean.TRUE);
// errors is false since no error occurred
results.put("errors", Boolean.FALSE);
return results;
}
try {
// call the authPayment method
Map<String, Object> authPaymentResult = authPayment(dispatcher, userLogin, orh, orderPaymentPreference, totalRemaining, reAuth, transAmount);
// handle the response
if (authPaymentResult != null) {
// not null result means either an approval or decline; null would mean error
BigDecimal thisAmount = (BigDecimal) authPaymentResult.get("processAmount");
// process the auth results
try {
boolean processResult = processResult(dctx, authPaymentResult, userLogin, orderPaymentPreference, locale);
if (processResult) {
Map<String, Object> results = ServiceUtil.returnSuccess();
results.put("messages", authPaymentResult.get("customerRespMsgs"));
results.put("processAmount", thisAmount);
results.put("finished", Boolean.TRUE);
results.put("errors", Boolean.FALSE);
results.put("authCode", authPaymentResult.get("authCode"));
return results;
} else {
boolean needsNsfRetry = needsNsfRetry(orderPaymentPreference, authPaymentResult, delegator);
// if we are doing an NSF retry then also...
if (needsNsfRetry) {
// TODO: what do we do with this? we need to fail the auth but still allow the order through so it can be fixed later
// NOTE: this is called through a different path for auto re-orders, so it should be good to go... will leave this comment here just in case...
}
// if we have a failure at this point and no NSF retry is needed, then try other credit cards on file, if the user has any
if (!needsNsfRetry) {
// is this an auto-order?
if (UtilValidate.isNotEmpty(orderHeader.getString("autoOrderShoppingListId"))) {
GenericValue productStore = orderHeader.getRelatedOne("ProductStore", false);
// according to the store should we try other cards?
if ("Y".equals(productStore.getString("autoOrderCcTryOtherCards"))) {
// get other credit cards for the bill to party
List<GenericValue> otherPaymentMethodAndCreditCardList = null;
String billToPartyId = null;
GenericValue billToParty = orh.getBillToParty();
if (billToParty != null) {
billToPartyId = billToParty.getString("partyId");
} else {
// TODO optional: any other ways to find the bill to party? perhaps look at info from OrderPaymentPreference, ie search back from other PaymentMethod...
}
if (UtilValidate.isNotEmpty(billToPartyId)) {
otherPaymentMethodAndCreditCardList = EntityQuery.use(delegator).from("PaymentMethodAndCreditCard").where("partyId", billToPartyId, "paymentMethodTypeId", "CREDIT_CARD").filterByDate().queryList();
}
if (UtilValidate.isNotEmpty(otherPaymentMethodAndCreditCardList)) {
for (GenericValue otherPaymentMethodAndCreditCard : otherPaymentMethodAndCreditCardList) {
// change OrderPaymentPreference in memory only and call auth service
orderPaymentPreference.set("paymentMethodId", otherPaymentMethodAndCreditCard.getString("paymentMethodId"));
Map<String, Object> authRetryResult = authPayment(dispatcher, userLogin, orh, orderPaymentPreference, totalRemaining, reAuth, transAmount);
try {
boolean processRetryResult = processResult(dctx, authPaymentResult, userLogin, orderPaymentPreference, locale);
if (processRetryResult) {
// wow, we got here that means the other card was successful...
// on success save the OrderPaymentPreference, and then return finished (which will break from loop)
orderPaymentPreference.store();
Map<String, Object> results = ServiceUtil.returnSuccess();
results.put("messages", authRetryResult.get("customerRespMsgs"));
results.put("processAmount", thisAmount);
results.put("finished", Boolean.TRUE);
results.put("errors", Boolean.FALSE);
return results;
}
} catch (GeneralException e) {
String errMsg = "Error saving and processing payment authorization results: " + e.toString();
Debug.logError(e, errMsg + "; authRetryResult: " + authRetryResult, module);
Map<String, Object> results = ServiceUtil.returnSuccess();
results.put(ModelService.ERROR_MESSAGE, errMsg);
results.put("finished", Boolean.FALSE);
results.put("errors", Boolean.TRUE);
return results;
}
// if no sucess, fall through to return not finished
}
}
}
}
}
Map<String, Object> results = ServiceUtil.returnSuccess();
results.put("messages", authPaymentResult.get("customerRespMsgs"));
results.put("finished", Boolean.FALSE);
results.put("errors", Boolean.FALSE);
return results;
}
} catch (GeneralException e) {
String errMsg = "Error saving and processing payment authorization results: " + e.toString();
Debug.logError(e, errMsg + "; authPaymentResult: " + authPaymentResult, module);
Map<String, Object> results = ServiceUtil.returnSuccess();
results.put(ModelService.ERROR_MESSAGE, errMsg);
results.put("finished", Boolean.FALSE);
results.put("errors", Boolean.TRUE);
return results;
}
} else {
// error with payment processor; will try later
String errMsg = "Invalid Order Payment Preference: maxAmount is 0";
Debug.logInfo(errMsg, module);
Map<String, Object> results = ServiceUtil.returnSuccess();
results.put("finished", Boolean.FALSE);
results.put("errors", Boolean.TRUE);
results.put(ModelService.ERROR_MESSAGE, errMsg);
orderPaymentPreference.set("statusId", "PAYMENT_CANCELLED");
try {
orderPaymentPreference.store();
} catch (GenericEntityException e) {
Debug.logError(e, "ERROR: Problem setting OrderPaymentPreference status to CANCELLED", module);
}
return results;
}
} catch (GeneralException e) {
Debug.logError(e, "Error processing payment authorization", module);
return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "AccountingPaymentCannotBeAuthorized", UtilMisc.toMap("errroString", e.toString()), locale));
}
}
use of org.apache.ofbiz.service.LocalDispatcher in project ofbiz-framework by apache.
the class PaymentGatewayServices method processCaptureSplitPayment.
public static Map<String, Object> processCaptureSplitPayment(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");
GenericValue paymentPref = (GenericValue) context.get("orderPaymentPreference");
BigDecimal splitAmount = (BigDecimal) context.get("splitAmount");
String orderId = paymentPref.getString("orderId");
OrderReadHelper orh = new OrderReadHelper(delegator, orderId);
String statusId = "PAYMENT_NOT_AUTH";
if ("EXT_BILLACT".equals(paymentPref.getString("paymentMethodTypeId"))) {
statusId = "PAYMENT_NOT_RECEIVED";
} else if ("EXT_PAYPAL".equals(paymentPref.get("paymentMethodTypeId"))) {
statusId = "PAYMENT_AUTHORIZED";
}
// create a new payment preference
Debug.logInfo("Creating payment preference split", module);
String newPrefId = delegator.getNextSeqId("OrderPaymentPreference");
GenericValue newPref = delegator.makeValue("OrderPaymentPreference", UtilMisc.toMap("orderPaymentPreferenceId", newPrefId));
newPref.set("orderId", paymentPref.get("orderId"));
newPref.set("paymentMethodTypeId", paymentPref.get("paymentMethodTypeId"));
newPref.set("paymentMethodId", paymentPref.get("paymentMethodId"));
newPref.set("maxAmount", splitAmount);
newPref.set("statusId", statusId);
newPref.set("createdDate", UtilDateTime.nowTimestamp());
if (userLogin != null) {
newPref.set("createdByUserLogin", userLogin.getString("userLoginId"));
}
if (Debug.verboseOn()) {
Debug.logVerbose("New preference : " + newPref, module);
}
Map<String, Object> processorResult = null;
try {
// create the new payment preference
delegator.create(newPref);
// fake it and copy the existing auth with the remaining amount
if ("EXT_PAYPAL".equals(paymentPref.get("paymentMethodTypeId"))) {
String newAuthId = delegator.getNextSeqId("PaymentGatewayResponse");
GenericValue authTrans = getAuthTransaction(paymentPref);
GenericValue newAuthTrans = delegator.makeValue("PaymentGatewayResponse", authTrans);
newAuthTrans.set("paymentGatewayResponseId", newAuthId);
newAuthTrans.set("orderPaymentPreferenceId", newPref.get("orderPaymentPreferenceId"));
newAuthTrans.set("amount", splitAmount);
savePgr(dctx, newAuthTrans);
} else if ("PAYMENT_NOT_AUTH".equals(statusId)) {
// authorize the new preference
processorResult = authPayment(dispatcher, userLogin, orh, newPref, splitAmount, false, null);
if (processorResult != null) {
// process the auth results
boolean authResult = processResult(dctx, processorResult, userLogin, newPref, locale);
if (!authResult) {
Debug.logError("Authorization failed : " + newPref + " : " + processorResult, module);
}
} else {
Debug.logError("Payment not authorized : " + newPref + " (no process result)", module);
}
}
} catch (GenericEntityException e) {
Debug.logError(e, "ERROR: cannot create new payment preference : " + newPref, module);
} catch (GeneralException e) {
if (processorResult != null) {
Debug.logError(e, "Trouble processing the auth result: " + newPref + " : " + processorResult, module);
} else {
Debug.logError(e, "Trouble authorizing the payment: " + newPref, module);
}
}
return ServiceUtil.returnSuccess();
}
use of org.apache.ofbiz.service.LocalDispatcher in project ofbiz-framework by apache.
the class PaymentGatewayServices method refundOrderPaymentPreference.
public static Map<String, Object> refundOrderPaymentPreference(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");
BigDecimal amount = (BigDecimal) context.get("amount");
Locale locale = (Locale) context.get("locale");
GenericValue orderPaymentPreference = null;
try {
orderPaymentPreference = EntityQuery.use(delegator).from("OrderPaymentPreference").where("orderPaymentPreferenceId", orderPaymentPreferenceId).queryOne();
} catch (GenericEntityException e) {
Debug.logError(e, module);
return ServiceUtil.returnError(UtilProperties.getMessage(resource, "AccountingProblemGettingOrderPaymentPreferences", locale) + " " + orderPaymentPreferenceId);
}
// call the service refundPayment
Map<String, Object> refundResponse = null;
try {
Map<String, Object> serviceContext = new HashMap<>();
serviceContext.put("orderPaymentPreference", orderPaymentPreference);
serviceContext.put("refundAmount", amount);
serviceContext.put("userLogin", userLogin);
refundResponse = dispatcher.runSync("refundPayment", serviceContext, TX_TIME, true);
if (ServiceUtil.isError(refundResponse)) {
return ServiceUtil.returnError(ServiceUtil.getErrorMessage(refundResponse));
}
} catch (GenericServiceException e) {
Debug.logError(e, "Problem refunding payment through processor", module);
return ServiceUtil.returnError(UtilProperties.getMessage(resource, "AccountingPaymentRefundError", locale));
}
refundResponse.putAll(ServiceUtil.returnSuccess(UtilProperties.getMessage(resourceError, "AccountingPaymentRefundedSuccessfully", UtilMisc.toMap("paymentId", refundResponse.get("paymentId"), "refundAmount", refundResponse.get("refundAmount")), locale)));
return refundResponse;
}
Aggregations