📄 paymentgatewayservices.java
字号:
if (invoice == null) { Debug.logError("Could not locate invoice #" + invoiceId, module); return ServiceUtil.returnError("Could not locate invoice #" + invoiceId); } // get the OrderItemBilling records for this invoice List orderItemBillings = null; try { orderItemBillings = invoice.getRelated("OrderItemBilling"); } catch (GenericEntityException e) { Debug.logError("Trouble getting OrderItemBilling(s) from Invoice #" + invoiceId, module); return ServiceUtil.returnError("Trouble getting OrderItemBilling(s) from Invoice #" + invoiceId); } // check for an associated billing account String billingAccountId = invoice.getString("billingAccountId"); // make sure they are all for the same order String testOrderId = null; boolean allSameOrder = true; if (orderItemBillings != null) { Iterator oii = orderItemBillings.iterator(); while (oii.hasNext()) { GenericValue oib = (GenericValue) oii.next(); String orderId = oib.getString("orderId"); if (testOrderId == null) { testOrderId = orderId; } else { if (!orderId.equals(testOrderId)) { allSameOrder = false; break; } } } } if (testOrderId == null || !allSameOrder) { Debug.logWarning("Attempt to settle Invoice #" + invoiceId + " which contained none/multiple orders", module); return ServiceUtil.returnSuccess(); } // get the invoice amount (amount to bill) double invoiceTotal = InvoiceWorker.getInvoiceTotal(invoice); if (Debug.infoOn()) Debug.logInfo("(Capture) Invoice [#" + invoiceId + "] total: " + invoiceTotal, module); // now capture the order Map serviceContext = UtilMisc.toMap("userLogin", userLogin, "orderId", testOrderId, "invoiceId", invoiceId, "captureAmount", new Double(invoiceTotal)); if (UtilValidate.isNotEmpty(billingAccountId)) { serviceContext.put("billingAccountId", billingAccountId); } try { return dispatcher.runSync("captureOrderPayments", serviceContext); } catch (GenericServiceException e) { Debug.logError(e, "Trouble running captureOrderPayments service", module); return ServiceUtil.returnError("Trouble running captureOrderPayments service"); } } /** * 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 captureOrderPayments(DispatchContext dctx, Map context) { GenericDelegator 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"); Double captureAmount = (Double) context.get("captureAmount"); BigDecimal captureAmountBd = new BigDecimal(captureAmount.doubleValue()); Map result = new HashMap(); // get the order header and payment preferences GenericValue orderHeader = null; List paymentPrefs = null; try { orderHeader = delegator.findByPrimaryKey("OrderHeader", UtilMisc.toMap("orderId", orderId)); // get the payment prefs Map lookupMap = UtilMisc.toMap("orderId", orderId, "statusId", "PAYMENT_AUTHORIZED"); List orderList = UtilMisc.toList("-maxAmount"); paymentPrefs = delegator.findByAnd("OrderPaymentPreference", lookupMap, orderList); } catch (GenericEntityException gee) { Debug.logError(gee, "Problems getting entity record(s), see stack trace", module); result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_ERROR); result.put(ModelService.ERROR_MESSAGE, "ERROR: Could not get order information (" + gee.getMessage() + ")."); return result; } // error if no order was found if (orderHeader == null) { return ServiceUtil.returnError("Could not find OrderHeader with orderId: " + orderId + "; not processing payments."); } OrderReadHelper orh = new OrderReadHelper(orderHeader); // See if there is a billing account first. If so, just charge the captureAmount to the billing account via PaymentApplication GenericValue billingAccount = null; BigDecimal billingAccountAvail = null; BigDecimal billingAccountCaptureAmount = ZERO; Map billingAccountInfo = null; if (UtilValidate.isNotEmpty(billingAccountId)) { try { billingAccountInfo = dispatcher.runSync("calcBillingAccountBalance", UtilMisc.toMap("billingAccountId", billingAccountId)); } catch (GenericServiceException e) { Debug.logError(e, "Unable to get billing account information for #" + billingAccountId, module); } } if (billingAccountInfo != null) { billingAccount = (GenericValue) billingAccountInfo.get("billingAccount"); // use available to capture because we want to know how much we can charge to a billing account Double availableToCapture = (Double) billingAccountInfo.get("availableToCapture"); billingAccountAvail = new BigDecimal(availableToCapture.doubleValue()); } // if a billing account is used to pay for an order, then charge as much as we can to it before proceeding to other payment methods. if (billingAccount != null && billingAccountAvail != null) { try { // the amount to be "charged" to the billing account, which is the minimum of the amount the order wants to charge to the billing account // or the amount still available for capturing from the billing account or the total amount to be captured on the order BigDecimal billingAccountMaxAmount = new BigDecimal(orh.getBillingAccountMaxAmount()); billingAccountCaptureAmount = billingAccountMaxAmount.min(billingAccountAvail).min(captureAmountBd); Debug.logInfo("billing account avail = [" + billingAccountAvail + "] capture amount = [" + billingAccountCaptureAmount + "] maxAmount = ["+billingAccountMaxAmount+"]", module); // capturing to a billing account if amount is greater than zero if (billingAccountCaptureAmount.compareTo(ZERO) == 1) { Map tmpResult = dispatcher.runSync("captureBillingAccountPayment", UtilMisc.toMap("invoiceId", invoiceId, "billingAccountId", billingAccountId, "captureAmount", new Double(billingAccountCaptureAmount.doubleValue()), "userLogin", userLogin)); if (ServiceUtil.isError(tmpResult)) { return tmpResult; } // now, if the full amount had not been captured, then capture // it from other methods, otherwise return if (billingAccountCaptureAmount.compareTo(captureAmountBd) == -1) { BigDecimal outstandingAmount = captureAmountBd.subtract(billingAccountCaptureAmount).setScale(decimals, rounding); captureAmount = new Double(outstandingAmount.doubleValue()); } else { Debug.logInfo("Amount to capture [" + captureAmount + "] was fully captured in Payment [" + tmpResult.get("paymentId") + "].", module); result = ServiceUtil.returnSuccess(); result.put("processResult", "COMPLETE"); return result; } } } catch (GenericServiceException ex) { return ServiceUtil.returnError(ex.getMessage()); } } // return complete if no payment prefs were found if (paymentPrefs == null || paymentPrefs.size() == 0) { Debug.logWarning("No orderPaymentPreferences available to capture", module); result.put("processResult", "COMPLETE"); result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_SUCCESS); return result; } double orderTotal = orh.getOrderGrandTotal(); double totalPayments = PaymentWorker.getPaymentsTotal(orh.getOrderPayments()); double remainingTotal = orderTotal - totalPayments; if (Debug.infoOn()) Debug.logInfo("Capture Remaining Total: " + remainingTotal, module); // re-format the remaining total String currencyFormat = UtilProperties.getPropertyValue("general.properties", "currency.decimal.format", "##0.00"); DecimalFormat formatter = new DecimalFormat(currencyFormat); String remainingTotalString = formatter.format(remainingTotal); try { Number remaining = formatter.parse(remainingTotalString); if (remaining != null) { remainingTotal = remaining.doubleValue(); } } catch (ParseException e) { Debug.logError(e, "Problem getting parsed remaining total", module); return ServiceUtil.returnError("ERROR: Cannot parse grand total from formatted string; see logs"); } //Debug.logInfo("Formatted Remaining total : " + remainingTotal, module); if (captureAmount == null) { captureAmount = new Double(remainingTotal); } double amountToCapture = captureAmount.doubleValue(); if (Debug.infoOn()) Debug.logInfo("Actual Expected Capture Amount : " + amountToCapture, module); // iterate over the prefs and capture each one until we meet our total List finished = new ArrayList(); Iterator payments = paymentPrefs.iterator(); while (payments.hasNext()) { GenericValue paymentPref = (GenericValue) payments.next(); GenericValue authTrans = getAuthTransaction(paymentPref); if (authTrans == null) { continue; } Double authAmount = authTrans.getDouble("amount"); if (authAmount == null) authAmount = new Double(0.00); if (authAmount.doubleValue() == 0.00) { // nothing to capture Debug.logInfo("Nothing to capture; authAmount = 0", module); continue; } //Debug.log("Actual Auth amount : " + authAmount, module); // if the authAmount is more then the remaining total; just use remaining total if (authAmount.doubleValue() > remainingTotal) { authAmount = new Double(remainingTotal); } // if we have a billing account; total up auth + account available double amountToBillAccount = 0.00; if (billingAccountAvail != null) { amountToBillAccount = authAmount.doubleValue() + billingAccountAvail.doubleValue(); } // the amount for *this* capture double amountThisCapture = 0.00; // determine how much for *this* capture if (authAmount.doubleValue() >= amountToCapture) { // 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.doubleValue(); } else if (billingAccountAvail != null && amountToBillAccount >= amountToCapture) { // the provided billing account will cover the remaining; just capture what was autorized amountThisCapture = authAmount.doubleValue(); } 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.doubleValue(); } Debug.logInfo("Payment preference = [" + paymentPref + "] amount to capture = [" + amountToCapture +"] amount of this capture = [" + amountThisCapture +"] actual auth amount =[" + authAmount + "] amountToBillAccount = [" + amountToBillAccount + "]", module); Map captureResult = capturePayment(dctx, userLogin, orh, paymentPref, amountThisCapture); if (captureResult != null) { // credit card processors return captureAmount, but gift certificate processors return processAmount Double amountCaptured = (Double) captureResult.get("captureAmount"); if (amountCaptured == null) { amountCaptured = (Double) captureResult.get("processAmount"); } // decrease amount of next payment preference to capture if (amountCaptured != null) amountToCapture -= amountCaptured.doubleValue(); finished.add(captureResult); // add the invoiceId to the result for processing captureResult.put("invoiceId", invoiceId); // process the capture's results try {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -