1 24 package org.ofbiz.accounting.payment; 25 26 import java.text.DecimalFormat ; 27 import java.text.ParseException ; 28 import java.util.ArrayList ; 29 import java.util.Collection ; 30 import java.util.Date ; 31 import java.util.HashMap ; 32 import java.util.Iterator ; 33 import java.util.List ; 34 import java.util.Map ; 35 import java.util.Calendar ; 36 import java.util.Set ; 37 import java.math.BigDecimal ; 38 import java.sql.Timestamp ; 39 40 import org.ofbiz.accounting.invoice.InvoiceWorker; 41 import org.ofbiz.base.util.Debug; 42 import org.ofbiz.base.util.GeneralException; 43 import org.ofbiz.base.util.UtilDateTime; 44 import org.ofbiz.base.util.UtilMisc; 45 import org.ofbiz.base.util.UtilNumber; 46 import org.ofbiz.base.util.UtilProperties; 47 import org.ofbiz.base.util.UtilValidate; 48 import org.ofbiz.entity.GenericDelegator; 49 import org.ofbiz.entity.GenericEntityException; 50 import org.ofbiz.entity.GenericValue; 51 import org.ofbiz.entity.condition.EntityCondition; 52 import org.ofbiz.entity.condition.EntityConditionList; 53 import org.ofbiz.entity.condition.EntityExpr; 54 import org.ofbiz.entity.condition.EntityJoinOperator; 55 import org.ofbiz.entity.condition.EntityOperator; 56 import org.ofbiz.entity.util.EntityListIterator; 57 import org.ofbiz.entity.util.EntityUtil; 58 import org.ofbiz.order.order.OrderChangeHelper; 59 import org.ofbiz.order.order.OrderReadHelper; 60 import org.ofbiz.party.contact.ContactHelper; 61 import org.ofbiz.product.store.ProductStoreWorker; 62 import org.ofbiz.security.Security; 63 import org.ofbiz.service.DispatchContext; 64 import org.ofbiz.service.GenericServiceException; 65 import org.ofbiz.service.LocalDispatcher; 66 import org.ofbiz.service.ModelService; 67 import org.ofbiz.service.ServiceUtil; 68 69 76 public class PaymentGatewayServices { 77 78 public static final String module = PaymentGatewayServices.class.getName(); 79 public static final String AUTH_SERVICE_TYPE = "PRDS_PAY_AUTH"; 80 public static final String REAUTH_SERVICE_TYPE = "PRDS_PAY_REAUTH"; 81 public static final String RELEASE_SERVICE_TYPE = "PRDS_PAY_RELEASE"; 82 public static final String CAPTURE_SERVICE_TYPE = "PRDS_PAY_CAPTURE"; 83 public static final String REFUND_SERVICE_TYPE = "PRDS_PAY_REFUND"; 84 public static final String CREDIT_SERVICE_TYPE = "PRDS_PAY_CREDIT"; 85 private static final int TX_TIME = 300; 86 private static BigDecimal ZERO = new BigDecimal ("0"); 87 private static int decimals = -1; 88 private static int rounding = -1; 89 static { 90 decimals = UtilNumber.getBigDecimalScale("order.decimals"); 91 rounding = UtilNumber.getBigDecimalRoundingMode("order.rounding"); 92 93 if (decimals != -1) ZERO.setScale(decimals); 95 } 96 97 100 private static double getTotalRemaining(OrderReadHelper orh) throws ParseException , NumberFormatException { 101 String currencyFormat = UtilProperties.getPropertyValue("general.properties", "currency.decimal.format", "##0.00"); 102 DecimalFormat formatter = new DecimalFormat (currencyFormat); 103 String grandTotalString = formatter.format(orh.getOrderGrandTotal()); 104 Double grandTotal = new Double (formatter.parse(grandTotalString).doubleValue()); 105 return grandTotal.doubleValue(); 106 } 107 108 114 public static Map authOrderPaymentPreference(DispatchContext dctx, Map context) { 115 GenericDelegator delegator = dctx.getDelegator(); 116 LocalDispatcher dispatcher = dctx.getDispatcher(); 117 GenericValue userLogin = (GenericValue) context.get("userLogin"); 118 119 String orderPaymentPreferenceId = (String ) context.get("orderPaymentPreferenceId"); 120 Double overrideAmount = (Double ) context.get("overrideAmount"); 121 122 if (overrideAmount != null) { 124 if (overrideAmount.doubleValue() < 0) return ServiceUtil.returnError("Amount entered (" + overrideAmount + ") is negative."); 125 if (overrideAmount.doubleValue() == 0) return ServiceUtil.returnError("Amount entered (" + overrideAmount + ") is zero."); 126 } 127 128 GenericValue orderHeader = null; 129 GenericValue orderPaymentPreference = null; 130 try { 131 orderPaymentPreference = delegator.findByPrimaryKey("OrderPaymentPreference", UtilMisc.toMap("orderPaymentPreferenceId", orderPaymentPreferenceId)); 132 orderHeader = orderPaymentPreference.getRelatedOne("OrderHeader"); 133 } catch (GenericEntityException e) { 134 Debug.logError(e, module); 135 return ServiceUtil.returnError("Problems getting required information: orderPaymentPreference [" + orderPaymentPreferenceId + "]"); 136 } 137 OrderReadHelper orh = new OrderReadHelper(orderHeader); 138 139 double totalRemaining = 0.0; 141 try { 142 totalRemaining = getTotalRemaining(orh); 143 } catch (Exception e) { 144 Debug.logError(e, "Problem getting parsed grand total amount", module); 145 return ServiceUtil.returnError("ERROR: Cannot parse grand total from formatted string; see logs"); 146 } 147 148 Long procAttempt = orderPaymentPreference.getLong("processAttempt"); 150 if (procAttempt == null) { 151 procAttempt = new Long (0); 152 } 153 154 orderPaymentPreference.set("processAttempt", new Long (procAttempt.longValue() + 1)); 156 try { 157 orderPaymentPreference.store(); 158 } catch (GenericEntityException e) { 159 Debug.logError(e, module); 160 return ServiceUtil.returnError("Unable to update OrderPaymentPreference record!"); 161 } 162 163 boolean reAuth = false; 165 if (orderPaymentPreference.get("statusId") != null && "PAYMENT_AUTHORIZED".equals(orderPaymentPreference.getString("statusId"))) { 166 reAuth = true; 167 } 168 169 Double transAmount = null; 171 if (overrideAmount != null) { 172 transAmount = overrideAmount; 173 } else { 174 transAmount = orderPaymentPreference.getDouble("maxAmount"); 175 } 176 177 Map results = UtilMisc.toMap(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_SUCCESS, "finished", new Boolean (false), "errors", new Boolean (false)); 179 180 if ((transAmount != null) && (transAmount.doubleValue() <= 0)) { 182 return results; 183 } 184 185 Map processorResult = authPayment(dispatcher, userLogin, orh, orderPaymentPreference, totalRemaining, reAuth, overrideAmount); 187 188 if (processorResult != null) { 190 191 if (processorResult.get("customerRespMsgs") != null) { 193 results.put("messages", processorResult.get("customerRespMsgs")); 194 } 195 196 Double thisAmount = (Double ) processorResult.get("processAmount"); 198 199 boolean processResult = false; 201 try { 202 processResult = processResult(dctx, processorResult, userLogin, orderPaymentPreference); 203 if (processResult) { 204 results.put("processAmount", thisAmount); 205 results.put("finished", new Boolean (true)); 206 } 207 } catch (GeneralException e) { 208 Debug.logError(e, "Trouble processing the result; processorResult: " + processorResult, module); 209 results.put("errors", new Boolean (true)); 210 } 211 } else { 212 Debug.logInfo("Invalid OrderPaymentPreference; maxAmount is 0", module); 214 orderPaymentPreference.set("statusId", "PAYMENT_CANCELLED"); 215 try { 216 orderPaymentPreference.store(); 217 } catch (GenericEntityException e) { 218 Debug.logError(e, "ERROR: Problem setting OrderPaymentPreference status to CANCELLED", module); 219 } 220 results.put("errors", new Boolean (true)); 221 } 222 return results; 223 } 224 225 229 public static Map authOrderPayments(DispatchContext dctx, Map context) { 230 GenericDelegator delegator = dctx.getDelegator(); 231 LocalDispatcher dispatcher = dctx.getDispatcher(); 232 String orderId = (String ) context.get("orderId"); 233 Map result = new HashMap (); 234 235 GenericValue orderHeader = null; 237 List paymentPrefs = null; 238 239 try { 240 orderHeader = delegator.findByPrimaryKey("OrderHeader", UtilMisc.toMap("orderId", orderId)); 242 243 Map lookupMap = UtilMisc.toMap("orderId", orderId, "statusId", "PAYMENT_NOT_AUTH"); 245 List orderList = UtilMisc.toList("maxAmount"); 246 paymentPrefs = delegator.findByAnd("OrderPaymentPreference", lookupMap, orderList); 247 } catch (GenericEntityException gee) { 248 Debug.logError(gee, "Problems getting the order information", module); 249 result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_ERROR); 250 result.put(ModelService.ERROR_MESSAGE, "ERROR: Could not get order information (" + gee.getMessage() + ")."); 251 return result; 252 } 253 254 if (orderHeader == null) { 256 return ServiceUtil.returnError("Could not find OrderHeader with orderId: " + orderId + "; not processing payments."); 257 } 258 259 OrderReadHelper orh = new OrderReadHelper(orderHeader); 261 double totalRemaining = 0.0; 262 try { 263 totalRemaining = getTotalRemaining(orh); 264 } catch (Exception e) { 265 Debug.logError(e, "Problem getting parsed grand total amount", module); 266 return ServiceUtil.returnError("ERROR: Cannot parse grand total from formatted string; see logs"); 267 } 268 269 int finished = 0; 271 int hadError = 0; 272 List messages = new ArrayList (); 273 Iterator payments = paymentPrefs.iterator(); 274 while (payments.hasNext()) { 275 GenericValue paymentPref = (GenericValue) payments.next(); 276 277 Map authContext = new HashMap (); 278 authContext.put("orderPaymentPreferenceId", paymentPref.getString("orderPaymentPreferenceId")); 279 authContext.put("userLogin", context.get("userLogin")); 280 281 Map results = null; 282 try { 283 results = dispatcher.runSync("authOrderPaymentPreference", authContext); 284 } catch (GenericServiceException se) { 285 Debug.logError(se, "Error in calling authOrderPaymentPreference from authOrderPayments: " + se.getMessage(), module); 286 hadError += 1; 287 messages.add("Could not authorize OrderPaymentPreference [" + paymentPref.getString("orderPaymentPreferenceId") + "] for order [" + orderId + "]: " 288 + se.getMessage()); 289 continue; 290 } 291 292 if (ServiceUtil.isError(results)) { 293 hadError += 1; 294 messages.add("Could not authorize OrderPaymentPreference [" + paymentPref.getString("orderPaymentPreferenceId") + "] for order [" + orderId + "]: " 295 + results.get(ModelService.ERROR_MESSAGE)); 296 continue; 297 } 298 299 if (((Boolean )results.get("finished")).booleanValue()) finished += 1; 300 if (((Boolean )results.get("errors")).booleanValue()) hadError += 1; 301 if (results.get("messages") != null) messages.addAll((List ) results.get("messages")); 302 if (results.get("processAmount") != null) totalRemaining -= ((Double ) results.get("processAmount")).doubleValue(); 303 } 304 305 Debug.logInfo("Finished with auth(s) checking results", module); 306 307 result.put("authResultMsgs", messages); 309 310 if (hadError > 0) { 311 Debug.logError("Error(s) (" + hadError + ") during auth; returning ERROR", module); 312 result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_SUCCESS); 313 result.put("processResult", "ERROR"); 314 return result; 315 } else if (finished == paymentPrefs.size()) { 316 Debug.logInfo("All auth(s) passed total remaining : " + totalRemaining, module); 317 result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_SUCCESS); 318 result.put("processResult", "APPROVED"); 319 return result; 320 } else { 321 Debug.logInfo("Only (" + finished + ") passed auth; returning FAILED", module); 322 result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_SUCCESS); 323 result.put("processResult", "FAILED"); 324 return result; 325 } 326 } 327 328 329 private static Map authPayment(LocalDispatcher dispatcher, GenericValue userLogin, OrderReadHelper orh, GenericValue paymentPref, double totalRemaining, boolean reauth) { 330 return authPayment(dispatcher, userLogin, orh, paymentPref, totalRemaining, reauth, null); 331 } 332 333 private static Map authPayment(LocalDispatcher dispatcher, GenericValue userLogin, OrderReadHelper orh, GenericValue paymentPref, double totalRemaining, boolean reauth, Double overrideAmount) { 334 String paymentConfig = null; 335 String serviceName = null; 336 337 String serviceType = AUTH_SERVICE_TYPE; 339 if (reauth) { 340 serviceType = REAUTH_SERVICE_TYPE; 341 } 342 343 GenericValue paymentSettings = getPaymentSettings(orh.getOrderHeader(), paymentPref, serviceType, false); 344 if (paymentSettings != null) { 345 serviceName = paymentSettings.getString("paymentService"); 346 paymentConfig = paymentSettings.getString("paymentPropertiesPath"); 347 } else { 348 Debug.logError("Invalid payment settings entity, no payment settings found", module); 349 return null; 350 } 351 352 if (serviceName == null) { 354 Debug.logError("Invalid payment processor: + " + paymentSettings, module); 355 return null; 356 } 357 358 Map processContext = null; 360 try { 361 processContext = makeAuthContext(orh, userLogin, paymentPref, paymentConfig, totalRemaining, overrideAmount); 362 } catch (GeneralException e) { 363 Debug.logError(e, "Problems creating the context for the auth service", module); 364 return null; 365 } 366 367 Map processorResult = null; 369 try { 370 processorResult = dispatcher.runSync(serviceName, processContext, TX_TIME, true); 372 } catch (GenericServiceException gse) { 373 Debug.logError("Error occurred on: " + serviceName + " => " + processContext, module); 374 Debug.logError(gse, "Problems invoking payment processor! Will retry later." + "(" + orh.getOrderId() + ")", module); 375 return null; 376 } 377 378 if (processorResult != null) { 379 String resultResponseCode = (String ) processorResult.get(ModelService.RESPONSE_MESSAGE); 381 if (resultResponseCode != null && resultResponseCode.equals(ModelService.RESPOND_ERROR)) { 382 Debug.logError("Processor failed; will retry later : " + processorResult.get(ModelService.ERROR_MESSAGE), module); 383 saveError(dispatcher, userLogin, paymentPref, processorResult, "PRDS_PAY_AUTH", "PGT_AUTHORIZE"); 385 return null; 386 } 387 388 String payToPartyId = getPayToPartyId(orh.getOrderHeader()); 390 processorResult.put("payToPartyId", payToPartyId); 391 392 processorResult.put("paymentSettings", paymentSettings); 394 395 processorResult.put("currencyUomId", orh.getCurrency()); 397 } 398 399 return processorResult; 400 } 401 402 private static GenericValue getPaymentSettings(GenericValue orderHeader, GenericValue paymentPreference, String paymentServiceType, boolean anyServiceType) { 403 GenericDelegator delegator = orderHeader.getDelegator(); 404 GenericValue paymentSettings = null; 405 GenericValue paymentMethod = null; 406 try { 407 paymentMethod = paymentPreference.getRelatedOne("PaymentMethod"); 408 } catch (GenericEntityException e) { 409 Debug.logError(e, "Problem getting PaymentMethod from OrderPaymentPreference", module); 410 } 411 if (paymentMethod != null) { 412 String productStoreId = orderHeader.getString("productStoreId"); 413 String paymentMethodTypeId = paymentMethod.getString("paymentMethodTypeId"); 414 if (productStoreId != null && paymentMethodTypeId != null) { 415 paymentSettings = ProductStoreWorker.getProductStorePaymentSetting(delegator, productStoreId, paymentMethodTypeId, paymentServiceType, anyServiceType); 416 } 417 } 418 return paymentSettings; 419 } 420 421 private static String getPayToPartyId(GenericValue orderHeader) { 422 String payToPartyId = "Company"; GenericValue productStore = null; 424 try { 425 productStore = orderHeader.getRelatedOne("ProductStore"); 426 } catch (GenericEntityException e) { 427 Debug.logError(e, "Unable to get ProductStore from OrderHeader", module); 428 return null; 429 } 430 if (productStore != null && productStore.get("payToPartyId") != null) { 431 payToPartyId = productStore.getString("payToPartyId"); 432 } else { 433 Debug.logWarning("Using default value of [Company] for payToPartyId on order [" + orderHeader.getString("orderId") + "]", module); 434 } 435 return payToPartyId; 436 } 437 438 private static Map makeAuthContext(OrderReadHelper orh, GenericValue userLogin, GenericValue paymentPreference, String paymentConfig, double totalRemaining, Double overrideAmount) throws GeneralException { 439 Map processContext = new HashMap (); 440 441 GenericValue orderHeader = orh.getOrderHeader(); 443 if (orderHeader != null) { 444 String visitId = orderHeader.getString("visitId"); 445 GenericValue visit = null; 446 if (visitId != null) { 447 try { 448 visit = orderHeader.getDelegator().findByPrimaryKey("Visit", UtilMisc.toMap("visitId", visitId)); 449 } catch (GenericEntityException e) { 450 Debug.logError(e, module); 451 } 452 } 453 454 if (visit != null && visit.get("clientIpAddress") != null) { 455 processContext.put("customerIpAddress", visit.getString("clientIpAddress")); 456 } 457 } 458 459 processContext.put("userLogin", userLogin); 460 processContext.put("orderId", orh.getOrderId()); 461 processContext.put("orderItems", orh.getOrderItems()); 462 processContext.put("shippingAddress", EntityUtil.getFirst(orh.getShippingLocations())); processContext.put("paymentConfig", paymentConfig); 464 processContext.put("currency", orh.getCurrency()); 465 processContext.put("orderPaymentPreference", paymentPreference); 466 if (paymentPreference.get("securityCode") != null) { 467 processContext.put("cardSecurityCode", paymentPreference.get("securityCode")); 468 } 469 470 getBillingInformation(orh, paymentPreference, processContext); 472 473 double thisAmount = totalRemaining; 475 476 if (overrideAmount != null) { 478 thisAmount = overrideAmount.doubleValue(); 479 } else if (paymentPreference.get("maxAmount") != null) { 480 thisAmount = paymentPreference.getDouble("maxAmount").doubleValue(); 481 } 482 483 if (thisAmount > totalRemaining) { 485 thisAmount = totalRemaining; 486 } 487 488 String currencyFormat = UtilProperties.getPropertyValue("general.properties", "currency.decimal.format", "##0.00"); 490 DecimalFormat formatter = new DecimalFormat (currencyFormat); 491 String amountString = formatter.format(thisAmount); 492 Double processAmount = null; 493 try { 494 processAmount = new Double (formatter.parse(amountString).doubleValue()); 495 } catch (ParseException e) { 496 Debug.logError(e, "Problems parsing string formatted double to Double", module); 497 throw new GeneralException("ParseException in number format", e); 498 } 499 500 if (Debug.verboseOn()) 501 Debug.logVerbose("Charging amount: " + processAmount, module); 502 processContext.put("processAmount", processAmount); 503 504 return processContext; 505 } 506 507 private static String getBillingInformation(OrderReadHelper orh, GenericValue paymentPreference, Map toContext) throws GenericEntityException { 508 GenericValue paymentMethod = paymentPreference.getRelatedOne("PaymentMethod"); 510 if (paymentMethod != null && paymentMethod.getString("paymentMethodTypeId").equals("CREDIT_CARD")) { 511 GenericValue creditCard = paymentMethod.getRelatedOne("CreditCard"); 513 GenericValue billingAddress = creditCard.getRelatedOne("PostalAddress"); 514 toContext.put("creditCard", creditCard); 515 toContext.put("billingAddress", billingAddress); 516 } else if (paymentMethod != null && paymentMethod.getString("paymentMethodTypeId").equals("EFT_ACCOUNT")) { 517 GenericValue eftAccount = paymentMethod.getRelatedOne("EftAccount"); 519 GenericValue billingAddress = eftAccount.getRelatedOne("PostalAddress"); 520 toContext.put("eftAccount", eftAccount); 521 toContext.put("billingAddress", billingAddress); 522 } else if (paymentMethod != null && paymentMethod.getString("paymentMethodTypeId").equals("GIFT_CARD")) { 523 GenericValue giftCard = paymentMethod.getRelatedOne("GiftCard"); 525 toContext.put("giftCard", giftCard); 526 } else { 527 Debug.logError("ERROR: Unsupported PaymentMethodType passed for authorization", module); 530 return null; 531 } 532 533 GenericValue billToPersonOrGroup = orh.getBillToParty(); 535 GenericValue billToEmail = null; 536 537 Collection emails = ContactHelper.getContactMech(billToPersonOrGroup.getRelatedOne("Party"), "PRIMARY_EMAIL", "EMAIL_ADDRESS", false); 538 539 if (UtilValidate.isNotEmpty(emails)) { 540 billToEmail = (GenericValue) emails.iterator().next(); 541 } 542 543 toContext.put("billToParty", billToPersonOrGroup); 544 toContext.put("billToEmail", billToEmail); 545 546 return billToPersonOrGroup.getString("partyId"); 547 } 548 549 554 public static Map releaseOrderPayments(DispatchContext dctx, Map context) { 555 GenericDelegator delegator = dctx.getDelegator(); 556 LocalDispatcher dispatcher = dctx.getDispatcher(); 557 GenericValue userLogin = (GenericValue) context.get("userLogin"); 558 String orderId = (String ) context.get("orderId"); 559 560 Map result = new HashMap (); 561 562 List paymentPrefs = null; 564 565 try { 566 List othExpr = UtilMisc.toList(new EntityExpr("paymentMethodTypeId", EntityOperator.EQUALS, "EFT_ACCOUNT")); 568 othExpr.add(new EntityExpr("paymentMethodTypeId", EntityOperator.EQUALS, "CREDIT_CARD")); 569 othExpr.add(new EntityExpr("paymentMethodTypeId", EntityOperator.EQUALS, "GIFT_CARD")); 570 EntityCondition con1 = new EntityConditionList(othExpr, EntityJoinOperator.OR); 571 572 EntityCondition statExpr = new EntityExpr("statusId", EntityOperator.EQUALS, "PAYMENT_SETTLED"); 573 EntityCondition con2 = new EntityConditionList(UtilMisc.toList(con1, statExpr), EntityOperator.AND); 574 575 EntityCondition authExpr = new EntityExpr("statusId", EntityOperator.EQUALS, "PAYMENT_AUTHORIZED"); 576 EntityCondition con3 = new EntityConditionList(UtilMisc.toList(con2, authExpr), EntityOperator.OR); 577 578 EntityExpr orderExpr = new EntityExpr("orderId", EntityOperator.EQUALS, orderId); 579 EntityCondition con4 = new EntityConditionList(UtilMisc.toList(con3, orderExpr), EntityOperator.AND); 580 581 paymentPrefs = delegator.findByCondition("OrderPaymentPreference", con4, null, null); 582 } catch (GenericEntityException gee) { 583 Debug.logError(gee, "Problems getting entity record(s), see stack trace", module); 584 result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_ERROR); 585 result.put(ModelService.ERROR_MESSAGE, "ERROR: Could not get order information (" + gee.toString() + ")."); 586 return result; 587 } 588 589 if (paymentPrefs == null || paymentPrefs.size() == 0) { 591 Debug.logWarning("No OrderPaymentPreference records available for release", module); 592 result.put("processResult", "COMPLETE"); 593 result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_SUCCESS); 594 return result; 595 } 596 597 List finished = new ArrayList (); 599 Iterator payments = paymentPrefs.iterator(); 600 while (payments.hasNext()) { 601 GenericValue paymentPref = (GenericValue) payments.next(); 602 Map releaseContext = UtilMisc.toMap("userLogin", userLogin, "orderPaymentPreferenceId", paymentPref.getString("orderPaymentPreferenceId")); 603 Map releaseResult = null; 604 try { 605 releaseResult = dispatcher.runSync("releaseOrderPaymentPreference", releaseContext); 606 } catch( GenericServiceException e ) { 607 String errMsg = "Problem calling releaseOrderPaymentPreference service for orderPaymentPreferenceId" + paymentPref.getString("orderPaymentPreferenceId"); 608 Debug.logError(e, errMsg, module); 609 return ServiceUtil.returnError(errMsg); 610 } 611 if (ServiceUtil.isError(releaseResult)) { 612 Debug.logError(ServiceUtil.getErrorMessage(releaseResult), module); 613 return ServiceUtil.returnError(ServiceUtil.getErrorMessage(releaseResult)); 614 } else if (! ServiceUtil.isFailure(releaseResult)) { 615 finished.add(paymentPref); 616 } 617 } 618 result = ServiceUtil.returnSuccess(); 619 if (finished.size() == paymentPrefs.size()) { 620 result.put("processResult", "COMPLETE"); 621 } else { 622 result.put("processResult", "FAILED"); 623 } 624 625 return result; 626 } 627 628 633 public static Map releaseOrderPaymentPreference(DispatchContext dctx, Map context) { 634 GenericDelegator delegator = dctx.getDelegator(); 635 LocalDispatcher dispatcher = dctx.getDispatcher(); 636 GenericValue userLogin = (GenericValue) context.get("userLogin"); 637 String orderPaymentPreferenceId = (String ) context.get("orderPaymentPreferenceId"); 638 639 Map result = ServiceUtil.returnSuccess(); 640 641 GenericValue paymentPref = null; 643 try { 644 paymentPref = delegator.findByPrimaryKey("OrderPaymentPreference", UtilMisc.toMap("orderPaymentPreferenceId", orderPaymentPreferenceId)); 645 } catch( GenericEntityException e ) { 646 String errMsg = "Problem getting OrderPaymentPreference for orderPaymentPreferenceId " + orderPaymentPreferenceId; 647 Debug.logWarning(e, errMsg, module); 648 return ServiceUtil.returnError(errMsg); 649 } 650 651 if (paymentPref == null) { 653 String errMsg = "Could not find OrderPaymentPreference with orderPaymentPreferenceId: " + orderPaymentPreferenceId; 654 Debug.logWarning(errMsg, module); 655 return ServiceUtil.returnError(errMsg); 656 } 657 658 GenericValue orderHeader = null; 660 try { 661 orderHeader = delegator.findByPrimaryKey("OrderHeader", UtilMisc.toMap("orderId", paymentPref.getString("orderId"))); 662 } catch( GenericEntityException e ) { 663 String errMsg = "Problem getting OrderHeader for orderId " + paymentPref.getString("orderId"); 664 Debug.logWarning(e, errMsg, module); 665 return ServiceUtil.returnError(errMsg); 666 } 667 668 if (orderHeader == null) { 670 String errMsg = "Could not find OrderHeader with orderId: " + paymentPref.getString("orderId") + "; not processing payments."; 671 Debug.logWarning(errMsg, module); 672 return ServiceUtil.returnError(errMsg); 673 } 674 675 OrderReadHelper orh = new OrderReadHelper(orderHeader); 676 String currency = orh.getCurrency(); 677 678 String serviceName = null; 680 String paymentConfig = null; 681 682 GenericValue paymentSettings = getPaymentSettings(orderHeader, paymentPref, RELEASE_SERVICE_TYPE, false); 684 if (paymentSettings != null) { 685 paymentConfig = paymentSettings.getString("paymentPropertiesPath"); 686 serviceName = paymentSettings.getString("paymentService"); 687 if (serviceName == null) { 688 String errMsg = "No payment release service for - " + paymentPref.getString("paymentMethodTypeId"); 689 Debug.logWarning(errMsg, module); 690 return ServiceUtil.returnError(errMsg); 691 } 692 } else { 693 String errMsg = "No payment release settings found for - " + paymentPref.getString("paymentMethodTypeId"); 694 Debug.logWarning(errMsg, module); 695 return ServiceUtil.returnError(errMsg); 696 } 697 698 if (paymentConfig == null || paymentConfig.length() == 0) { 699 paymentConfig = "payment.properties"; 700 } 701 702 GenericValue authTransaction = PaymentGatewayServices.getAuthTransaction(paymentPref); 703 Map releaseContext = new HashMap (); 704 releaseContext.put("orderPaymentPreference", paymentPref); 705 releaseContext.put("releaseAmount", authTransaction.getDouble("amount")); 706 releaseContext.put("currency", currency); 707 releaseContext.put("paymentConfig", paymentConfig); 708 releaseContext.put("userLogin", userLogin); 709 710 Map releaseResult = null; 712 try { 713 releaseResult = dispatcher.runSync(serviceName, releaseContext, TX_TIME, true); 714 } catch (GenericServiceException e) { 715 String errMsg = "Problem releasing payment"; 716 Debug.logError(e,errMsg, module); 717 return ServiceUtil.returnError(errMsg); 718 } 719 720 if (releaseResult != null && !ServiceUtil.isError(releaseResult)) { 722 Boolean releaseResponse = (Boolean ) releaseResult.get("releaseResult"); 723 724 String responseId = delegator.getNextSeqId("PaymentGatewayResponse"); 726 GenericValue pgResponse = delegator.makeValue("PaymentGatewayResponse", null); 727 pgResponse.set("paymentGatewayResponseId", responseId); 728 pgResponse.set("paymentServiceTypeEnumId", RELEASE_SERVICE_TYPE); 729 pgResponse.set("orderPaymentPreferenceId", paymentPref.get("orderPaymentPreferenceId")); 730 pgResponse.set("paymentMethodTypeId", paymentPref.get("paymentMethodTypeId")); 731 pgResponse.set("paymentMethodId", paymentPref.get("paymentMethodId")); 732 pgResponse.set("transCodeEnumId", "PGT_RELEASE"); 733 734 pgResponse.set("referenceNum", releaseResult.get("releaseRefNum")); 736 pgResponse.set("altReference", releaseResult.get("releaseAltRefNum")); 737 pgResponse.set("gatewayCode", releaseResult.get("releaseCode")); 738 pgResponse.set("gatewayFlag", releaseResult.get("releaseFlag")); 739 pgResponse.set("gatewayMessage", releaseResult.get("releaseMessage")); 740 pgResponse.set("transactionDate", UtilDateTime.nowTimestamp()); 741 742 try { 744 pgResponse.create(); 745 } catch (GenericEntityException e) { 746 Debug.logError(e, "Problem storing PaymentGatewayResponse entity; authorization was released! : " + pgResponse, module); 747 } 748 749 List messages = (List ) releaseResult.get("internalRespMsgs"); 751 if (messages != null && messages.size() > 0) { 752 Iterator i = messages.iterator(); 753 while (i.hasNext()) { 754 GenericValue respMsg = delegator.makeValue("PaymentGatewayRespMsg", null); 755 String respMsgId = delegator.getNextSeqId("PaymentGatewayRespMsg"); 756 String message = (String ) i.next(); 757 respMsg.set("paymentGatewayRespMsgId", respMsgId); 758 respMsg.set("paymentGatewayResponseId", responseId); 759 respMsg.set("pgrMessage", message); 760 try { 761 delegator.create(respMsg); 762 } catch (GenericEntityException e) { 763 String errMsg = "Unable to create PaymentGatewayRespMsg record"; 764 Debug.logError(e, errMsg, module); 765 return ServiceUtil.returnError(errMsg); 766 } 767 } 768 } 769 770 if (releaseResponse != null && releaseResponse.booleanValue()) { 771 paymentPref.set("statusId", "PAYMENT_CANCELLED"); 772 try { 773 paymentPref.store(); 774 } catch (GenericEntityException e) { 775 Debug.logError(e, "Problem storing updated payment preference; authorization was released!", module); 776 } 777 778 List paymentList = null; 780 try { 781 paymentList = paymentPref.getRelated("Payment"); 782 } catch (GenericEntityException e) { 783 Debug.logError(e, "Unable to get Payment records from OrderPaymentPreference : " + paymentPref, module); 784 } 785 786 if (paymentList != null) { 787 Iterator pi = paymentList.iterator(); 788 while (pi.hasNext()) { 789 GenericValue pay = (GenericValue) pi.next(); 790 pay.set("statusId", "PMNT_CANCELLED"); 791 try { 792 pay.store(); 793 } catch (GenericEntityException e) { 794 Debug.logError(e, "Unable to store Payment : " + pay, module); 795 } 796 } 797 } 798 } else { 799 String errMsg = "Release failed for pref : " + paymentPref; 800 Debug.logError(errMsg, module); 801 result = ServiceUtil.returnFailure(errMsg); 802 } 803 } else if (ServiceUtil.isError(releaseResult)) { 804 saveError(dispatcher, userLogin, paymentPref, releaseResult, "PRDS_PAY_RELEASE", "PGT_RELEASE"); 805 result = ServiceUtil.returnError(ServiceUtil.getErrorMessage(releaseResult)); 806 } 807 808 return result; 809 } 810 811 815 public static Map capturePaymentsByInvoice(DispatchContext dctx, Map context) { 816 GenericDelegator delegator = dctx.getDelegator(); 817 LocalDispatcher dispatcher = dctx.getDispatcher(); 818 GenericValue userLogin = (GenericValue) context.get("userLogin"); 819 String invoiceId = (String ) context.get("invoiceId"); 820 821 GenericValue invoice = null; 823 try { 824 invoice = delegator.findByPrimaryKey("Invoice", UtilMisc.toMap("invoiceId", invoiceId)); 825 } catch (GenericEntityException e) { 826 Debug.logError(e, "Trouble looking up Invoice #" + invoiceId, module); 827 return ServiceUtil.returnError("Trouble looking up Invoice #" + invoiceId); 828 } 829 830 if (invoice == null) { 831 Debug.logError("Could not locate invoice #" + invoiceId, module); 832 return ServiceUtil.returnError("Could not locate invoice #" + invoiceId); 833 } 834 835 List orderItemBillings = null; 837 try { 838 orderItemBillings = invoice.getRelated("OrderItemBilling"); 839 } catch (GenericEntityException e) { 840 Debug.logError("Trouble getting OrderItemBilling(s) from Invoice #" + invoiceId, module); 841 return ServiceUtil.returnError("Trouble getting OrderItemBilling(s) from Invoice #" + invoiceId); 842 } 843 844 String billingAccountId = invoice.getString("billingAccountId"); 846 847 String testOrderId = null; 849 boolean allSameOrder = true; 850 if (orderItemBillings != null) { 851 Iterator oii = orderItemBillings.iterator(); 852 while (oii.hasNext()) { 853 GenericValue oib = (GenericValue) oii.next(); 854 String orderId = oib.getString("orderId"); 855 if (testOrderId == null) { 856 testOrderId = orderId; 857 } else { 858 if (!orderId.equals(testOrderId)) { 859 allSameOrder = false; 860 break; 861 } 862 } 863 } 864 } 865 866 if (testOrderId == null || !allSameOrder) { 867 Debug.logWarning("Attempt to settle Invoice #" + invoiceId + " which contained none/multiple orders", module); 868 return ServiceUtil.returnSuccess(); 869 } 870 871 double invoiceTotal = InvoiceWorker.getInvoiceTotal(invoice); 873 if (Debug.infoOn()) Debug.logInfo("(Capture) Invoice [#" + invoiceId + "] total: " + invoiceTotal, module); 874 875 Map serviceContext = UtilMisc.toMap("userLogin", userLogin, "orderId", testOrderId, "invoiceId", invoiceId, "captureAmount", new Double (invoiceTotal)); 877 if (UtilValidate.isNotEmpty(billingAccountId)) { 878 serviceContext.put("billingAccountId", billingAccountId); 879 } 880 try { 881 return dispatcher.runSync("captureOrderPayments", serviceContext); 882 } catch (GenericServiceException e) { 883 Debug.logError(e, "Trouble running captureOrderPayments service", module); 884 return ServiceUtil.returnError("Trouble running captureOrderPayments service"); 885 } 886 } 887 888 892 public static Map captureOrderPayments(DispatchContext dctx, Map context) { 893 GenericDelegator delegator = dctx.getDelegator(); 894 LocalDispatcher dispatcher = dctx.getDispatcher(); 895 GenericValue userLogin = (GenericValue) context.get("userLogin"); 896 String orderId = (String ) context.get("orderId"); 897 String invoiceId = (String ) context.get("invoiceId"); 898 String billingAccountId = (String ) context.get("billingAccountId"); 899 Double captureAmount = (Double ) context.get("captureAmount"); 900 BigDecimal captureAmountBd = new BigDecimal (captureAmount.doubleValue()); 901 902 Map result = new HashMap (); 903 904 GenericValue orderHeader = null; 906 List paymentPrefs = null; 907 908 try { 909 orderHeader = delegator.findByPrimaryKey("OrderHeader", UtilMisc.toMap("orderId", orderId)); 910 911 Map lookupMap = UtilMisc.toMap("orderId", orderId, "statusId", "PAYMENT_AUTHORIZED"); 913 List orderList = UtilMisc.toList("-maxAmount"); 914 paymentPrefs = delegator.findByAnd("OrderPaymentPreference", lookupMap, orderList); 915 } catch (GenericEntityException gee) { 916 Debug.logError(gee, "Problems getting entity record(s), see stack trace", module); 917 result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_ERROR); 918 result.put(ModelService.ERROR_MESSAGE, "ERROR: Could not get order information (" + gee.getMessage() + ")."); 919 return result; 920 } 921 922 if (orderHeader == null) { 924 return ServiceUtil.returnError("Could not find OrderHeader with orderId: " + orderId + "; not processing payments."); 925 } 926 927 OrderReadHelper orh = new OrderReadHelper(orderHeader); 928 929 GenericValue billingAccount = null; 931 BigDecimal billingAccountAvail = null; 932 BigDecimal billingAccountCaptureAmount = ZERO; 933 Map billingAccountInfo = null; 934 if (UtilValidate.isNotEmpty(billingAccountId)) { 935 try { 936 billingAccountInfo = dispatcher.runSync("calcBillingAccountBalance", UtilMisc.toMap("billingAccountId", billingAccountId)); 937 } catch (GenericServiceException e) { 938 Debug.logError(e, "Unable to get billing account information for #" + billingAccountId, module); 939 } 940 } 941 if (billingAccountInfo != null) { 942 billingAccount = (GenericValue) billingAccountInfo.get("billingAccount"); 943 Double availableToCapture = (Double ) billingAccountInfo.get("availableToCapture"); 945 billingAccountAvail = new BigDecimal (availableToCapture.doubleValue()); 946 } 947 948 if (billingAccount != null && billingAccountAvail != null) { 950 try { 951 BigDecimal billingAccountMaxAmount = new BigDecimal (orh.getBillingAccountMaxAmount()); 954 billingAccountCaptureAmount = billingAccountMaxAmount.min(billingAccountAvail).min(captureAmountBd); 955 Debug.logInfo("billing account avail = [" + billingAccountAvail + "] capture amount = [" + billingAccountCaptureAmount + "] maxAmount = ["+billingAccountMaxAmount+"]", module); 956 if (billingAccountCaptureAmount.compareTo(ZERO) == 1) { 958 Map tmpResult = dispatcher.runSync("captureBillingAccountPayment", UtilMisc.toMap("invoiceId", invoiceId, "billingAccountId", billingAccountId, 959 "captureAmount", new Double (billingAccountCaptureAmount.doubleValue()), "userLogin", userLogin)); 960 if (ServiceUtil.isError(tmpResult)) { 961 return tmpResult; 962 } 963 964 if (billingAccountCaptureAmount.compareTo(captureAmountBd) == -1) { 967 BigDecimal outstandingAmount = captureAmountBd.subtract(billingAccountCaptureAmount).setScale(decimals, rounding); 968 captureAmount = new Double (outstandingAmount.doubleValue()); 969 } else { 970 Debug.logInfo("Amount to capture [" + captureAmount + "] was fully captured in Payment [" + tmpResult.get("paymentId") + "].", module); 971 result = ServiceUtil.returnSuccess(); 972 result.put("processResult", "COMPLETE"); 973 return result; 974 } 975 } 976 } catch (GenericServiceException ex) { 977 return ServiceUtil.returnError(ex.getMessage()); 978 } 979 } 980 981 if (paymentPrefs == null || paymentPrefs.size() == 0) { 983 Debug.logWarning("No orderPaymentPreferences available to capture", module); 984 result.put("processResult", "COMPLETE"); 985 result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_SUCCESS); 986 return result; 987 } 988 989 double orderTotal = orh.getOrderGrandTotal(); 990 double totalPayments = PaymentWorker.getPaymentsTotal(orh.getOrderPayments()); 991 double remainingTotal = orderTotal - totalPayments; 992 if (Debug.infoOn()) Debug.logInfo("Capture Remaining Total: " + remainingTotal, module); 993 994 String currencyFormat = UtilProperties.getPropertyValue("general.properties", "currency.decimal.format", "##0.00"); 996 DecimalFormat formatter = new DecimalFormat (currencyFormat); 997 String remainingTotalString = formatter.format(remainingTotal); 998 try { 999 Number remaining = formatter.parse(remainingTotalString); 1000 if (remaining != null) { 1001 remainingTotal = remaining.doubleValue(); 1002 } 1003 } catch (ParseException e) { 1004 Debug.logError(e, "Problem getting parsed remaining total", module); 1005 return ServiceUtil.returnError("ERROR: Cannot parse grand total from formatted string; see logs"); 1006 } 1007 1009 if (captureAmount == null) { 1010 captureAmount = new Double (remainingTotal); 1011 } 1012 double amountToCapture = captureAmount.doubleValue(); 1013 if (Debug.infoOn()) Debug.logInfo("Actual Expected Capture Amount : " + amountToCapture, module); 1014 1015 List finished = new ArrayList (); 1017 Iterator payments = paymentPrefs.iterator(); 1018 while (payments.hasNext()) { 1019 GenericValue paymentPref = (GenericValue) payments.next(); 1020 GenericValue authTrans = getAuthTransaction(paymentPref); 1021 if (authTrans == null) { 1022 continue; 1023 } 1024 1025 Double authAmount = authTrans.getDouble("amount"); 1026 if (authAmount == null) authAmount = new Double (0.00); 1027 if (authAmount.doubleValue() == 0.00) { 1028 Debug.logInfo("Nothing to capture; authAmount = 0", module); 1030 continue; 1031 } 1032 1034 if (authAmount.doubleValue() > remainingTotal) { 1036 authAmount = new Double (remainingTotal); 1037 } 1038 1039 double amountToBillAccount = 0.00; 1041 if (billingAccountAvail != null) { 1042 amountToBillAccount = authAmount.doubleValue() + billingAccountAvail.doubleValue(); 1043 } 1044 1045 double amountThisCapture = 0.00; 1047 1048 if (authAmount.doubleValue() >= amountToCapture) { 1050 amountThisCapture = amountToCapture; 1052 } else if (payments.hasNext()) { 1053 amountThisCapture = authAmount.doubleValue(); 1055 } else if (billingAccountAvail != null && amountToBillAccount >= amountToCapture) { 1056 amountThisCapture = authAmount.doubleValue(); 1058 } else { 1059 Debug.logError("The amount to capture was more then what was authorized; we only captured the authorized amount : " + paymentPref, module); 1064 amountThisCapture = authAmount.doubleValue(); 1065 } 1066 1067 Debug.logInfo("Payment preference = [" + paymentPref + "] amount to capture = [" + amountToCapture +"] amount of this capture = [" + amountThisCapture +"] actual auth amount =[" + authAmount + "] amountToBillAccount = [" + amountToBillAccount + "]", module); 1068 Map captureResult = capturePayment(dctx, userLogin, orh, paymentPref, amountThisCapture); 1069 if (captureResult != null) { 1070 Double amountCaptured = (Double ) captureResult.get("captureAmount"); 1072 if (amountCaptured == null) { 1073 amountCaptured = (Double ) captureResult.get("processAmount"); 1074 } 1075 if (amountCaptured != null) amountToCapture -= amountCaptured.doubleValue(); 1077 finished.add(captureResult); 1078 1079 captureResult.put("invoiceId", invoiceId); 1081 1082 try { 1084 processResult(dctx, captureResult, userLogin, paymentPref); 1085 } catch (GeneralException e) { 1086 Debug.logError(e, "Trouble processing the result; captureResult: " + captureResult, module); 1087 return ServiceUtil.returnError("Trouble processing the capture results"); 1088 } 1089 1090 BigDecimal totalAmountCaptured = new BigDecimal (amountThisCapture); 1092 if (authAmount.doubleValue() > totalAmountCaptured.doubleValue()) { 1093 double newAmount = authAmount.doubleValue() - totalAmountCaptured.doubleValue(); Debug.logInfo("Creating payment preference split", module); 1096 String newPrefId = delegator.getNextSeqId("OrderPaymentPreference"); 1097 GenericValue newPref = delegator.makeValue("OrderPaymentPreference", UtilMisc.toMap("orderPaymentPreferenceId", newPrefId)); 1098 newPref.set("orderId", paymentPref.get("orderId")); 1099 newPref.set("paymentMethodTypeId", paymentPref.get("paymentMethodTypeId")); 1100 newPref.set("paymentMethodId", paymentPref.get("paymentMethodId")); 1101 newPref.set("maxAmount", paymentPref.get("maxAmount")); 1102 newPref.set("statusId", "PAYMENT_NOT_AUTH"); 1103 newPref.set("createdDate", UtilDateTime.nowTimestamp()); 1104 if (userLogin != null) { 1105 newPref.set("createdByUserLogin", userLogin.getString("userLoginId")); 1106 } 1107 Debug.logInfo("New preference : " + newPref, module); 1108 try { 1109 delegator.create(newPref); 1111 1112 Map processorResult = authPayment(dispatcher, userLogin, orh, newPref, newAmount, false); 1114 if (processorResult != null) { 1115 boolean authResult = false; 1117 try { 1118 authResult = processResult(dctx, processorResult, userLogin, newPref); 1119 if (!authResult) { 1120 Debug.logError("Authorization failed : " + newPref + " : " + processorResult, module); 1121 } 1122 } catch (GeneralException e) { 1123 Debug.logError(e, "Trouble processing the auth result : " + newPref + " : " + processorResult, module); 1124 } 1125 } else { 1126 Debug.logError("Payment not authorized : " + newPref + " : " + processorResult, module); 1127 } 1128 } catch (GenericEntityException e) { 1129 Debug.logError(e, "ERROR: cannot create new payment preference : " + newPref, module); 1130 } 1131 } 1132 } else { 1133 Debug.logError("Payment not captured", module); 1134 continue; 1135 } 1136 } 1137 1138 if (amountToCapture > 0.00) { 1139 result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_SUCCESS); 1140 result.put("processResult", "FAILED"); 1141 return result; 1142 } else { 1143 result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_SUCCESS); 1144 result.put("processResult", "COMPLETE"); 1145 return result; 1146 } 1147 } 1148 1149 public static Map captureBillingAccountPayment(DispatchContext dctx, Map context) { 1150 GenericDelegator delegator = dctx.getDelegator(); 1151 LocalDispatcher dispatcher = dctx.getDispatcher(); 1152 GenericValue userLogin = (GenericValue) context.get("userLogin"); 1153 String invoiceId = (String ) context.get("invoiceId"); 1154 String billingAccountId = (String ) context.get("billingAccountId"); 1155 Double captureAmount = (Double ) context.get("captureAmount"); 1156 Map results = ServiceUtil.returnSuccess(); 1157 1158 try { 1159 GenericValue invoice = delegator.findByPrimaryKey("Invoice", UtilMisc.toMap("invoiceId", invoiceId)); 1161 Map paymentParams = UtilMisc.toMap("paymentTypeId", "CUSTOMER_PAYMENT", "paymentMethodTypeId", "EXT_BILLACT", 1162 "partyIdFrom", invoice.getString("partyId"), "partyIdTo", invoice.getString("partyIdFrom"), 1163 "statusId", "PMNT_RECEIVED", "effectiveDate", UtilDateTime.nowTimestamp()); 1164 paymentParams.put("amount", captureAmount); 1165 paymentParams.put("currencyUomId", invoice.getString("currencyUomId")); 1166 paymentParams.put("userLogin", userLogin); 1167 Map tmpResult = dispatcher.runSync("createPayment", paymentParams); 1168 if (ServiceUtil.isError(tmpResult)) { 1169 return tmpResult; 1170 } 1171 1172 String paymentId = (String ) tmpResult.get("paymentId"); 1173 tmpResult = dispatcher.runSync("createPaymentApplication", UtilMisc.toMap("paymentId", paymentId, "invoiceId", invoiceId, "billingAccountId", billingAccountId, 1174 "amountApplied", captureAmount, "userLogin", userLogin)); 1175 if (ServiceUtil.isError(tmpResult)) { 1176 return tmpResult; 1177 } 1178 if (paymentId == null) { 1179 return ServiceUtil.returnError("No payment created for invoice [" + invoiceId + "] and billing account [" + billingAccountId + "]"); 1180 } 1181 results.put("paymentId", paymentId); 1182 } catch (GenericEntityException ex) { 1183 return ServiceUtil.returnError(ex.getMessage()); 1184 } catch (GenericServiceException ex) { 1185 return ServiceUtil.returnError(ex.getMessage()); 1186 } 1187 1188 return results; 1189 } 1190 1191 private static Map capturePayment(DispatchContext dctx, GenericValue userLogin, OrderReadHelper orh, GenericValue paymentPref, double amount) { 1192 return capturePayment(dctx, userLogin, orh, paymentPref, amount, null); 1193 } 1194 1195 private static Map capturePayment(DispatchContext dctx, GenericValue userLogin, OrderReadHelper orh, GenericValue paymentPref, double amount, GenericValue authTrans) { 1196 LocalDispatcher dispatcher = dctx.getDispatcher(); 1197 String serviceName = null; 1199 String paymentConfig = null; 1200 1201 GenericValue paymentSettings = getPaymentSettings(orh.getOrderHeader(), paymentPref, CAPTURE_SERVICE_TYPE, false); 1203 if (paymentSettings != null) { 1204 paymentConfig = paymentSettings.getString("paymentPropertiesPath"); 1205 serviceName = paymentSettings.getString("paymentService"); 1206 if (serviceName == null) { 1207 Debug.logError("Service name is null for payment setting; cannot process", module); 1208 return null; 1209 } 1210 } else { 1211 Debug.logError("Invalid payment settings entity, no payment settings found", module); 1212 return null; 1213 } 1214 1215 if (paymentConfig == null || paymentConfig.length() == 0) { 1216 paymentConfig = "payment.properties"; 1217 } 1218 1219 if (!PaymentGatewayServices.checkAuthValidity(paymentPref, paymentConfig)) { 1221 Map processorResult = PaymentGatewayServices.authPayment(dispatcher, userLogin, orh, paymentPref, amount, true); 1223 1224 boolean authResult = false; 1225 if (processorResult != null) { 1226 try { 1228 authResult = processResult(dctx, processorResult, userLogin, paymentPref); 1229 if (!authResult) { 1230 Debug.logError("Re-Authorization failed : " + paymentPref + " : " + processorResult, module); 1231 } 1232 } catch (GeneralException e) { 1233 Debug.logError(e, "Trouble processing the re-auth result : " + paymentPref + " : " + processorResult, module); 1234 } 1235 } else { 1236 Debug.logError("Payment not re-authorized : " + paymentPref + " : " + processorResult, module); 1237 } 1238 1239 if (!authResult) { 1240 return null; 1242 } 1243 1244 authTrans = getAuthTransaction(paymentPref); 1246 } 1247 1248 Map captureContext = new HashMap (); 1250 captureContext.put("userLogin", userLogin); 1251 captureContext.put("orderPaymentPreference", paymentPref); 1252 captureContext.put("paymentConfig", paymentConfig); 1253 captureContext.put("currency", orh.getCurrency()); 1254 1255 try { 1257 ModelService captureService = dctx.getModelService(serviceName); 1258 Set inParams = captureService.getInParamNames(); 1259 if (inParams.contains("captureAmount")) { 1260 captureContext.put("captureAmount", new Double (amount)); 1261 } else if (inParams.contains("processAmount")) { 1262 captureContext.put("processAmount", new Double (amount)); 1263 } else { 1264 return ServiceUtil.returnError("Service [" + serviceName + "] does not have a captureAmount or processAmount. Its parameters are: " + inParams); 1265 } 1266 } catch (GenericServiceException ex) { 1267 return ServiceUtil.returnError("Cannot get model service for " + serviceName); 1268 } 1269 1270 1271 if (authTrans != null) { 1272 captureContext.put("authTrans", authTrans); 1273 } 1274 1275 Debug.logInfo("Capture [" + serviceName + "] : " + captureContext, module); 1276 1277 Map captureResult = null; 1279 try { 1280 captureResult = dispatcher.runSync(serviceName, captureContext, TX_TIME, true); 1281 } catch (GenericServiceException e) { 1282 Debug.logError(e, "Could not capture payment ... serviceName: " + serviceName + " ... context: " + captureContext, module); 1283 return null; 1284 } 1285 1286 String payToPartyId = getPayToPartyId(orh.getOrderHeader()); 1288 captureResult.put("payToPartyId", payToPartyId); 1289 1290 captureResult.put("paymentSettings", paymentSettings); 1292 1293 captureResult.put("currencyUomId", orh.getCurrency()); 1295 1296 if (ServiceUtil.isError(captureResult)) { 1298 saveError(dispatcher, userLogin, paymentPref, captureResult, "PRDS_PAY_CAPTURE", "PGT_CAPTURE"); 1299 } 1300 1301 return captureResult; 1302 } 1303 1304 private static void saveError(LocalDispatcher dispatcher, GenericValue userLogin, GenericValue paymentPref, Map result, String serviceType, String transactionCode) { 1305 Map serviceContext = new HashMap (); 1306 serviceContext.put("paymentServiceTypeEnumId", serviceType); 1307 serviceContext.put("orderPaymentPreference", paymentPref); 1308 serviceContext.put("transCodeEnumId", transactionCode); 1309 serviceContext.put("serviceResultMap", result); 1310 serviceContext.put("userLogin", userLogin); 1311 1312 try { 1313 dispatcher.runAsync("processPaymentServiceError", serviceContext); 1314 } catch (GenericServiceException e) { 1315 Debug.logError(e, module); 1316 } 1317 } 1318 1319 public static Map storePaymentErrorMessage(DispatchContext dctx, Map context) { 1320 GenericDelegator delegator = dctx.getDelegator(); 1321 GenericValue paymentPref = (GenericValue) context.get("orderPaymentPreference"); 1322 String serviceType = (String ) context.get("paymentServiceTypeEnumId"); 1323 String transactionCode = (String ) context.get("transCodeEnumId"); 1324 Map result = (Map ) context.get("serviceResultMap"); 1325 1326 String responseId = delegator.getNextSeqId("PaymentGatewayResponse"); 1327 GenericValue response = delegator.makeValue("PaymentGatewayResponse", null); 1328 response.set("paymentGatewayResponseId", responseId); 1329 response.set("paymentServiceTypeEnumId", serviceType); 1330 response.set("orderPaymentPreferenceId", paymentPref.get("orderPaymentPreferenceId")); 1331 response.set("paymentMethodTypeId", paymentPref.get("paymentMethodTypeId")); 1332 response.set("paymentMethodId", paymentPref.get("paymentMethodId")); 1333 response.set("transCodeEnumId", transactionCode); 1334 response.set("referenceNum", "ERROR"); 1335 response.set("gatewayMessage", ServiceUtil.getErrorMessage(result)); 1336 response.set("transactionDate", UtilDateTime.nowTimestamp()); 1337 1338 try { 1339 delegator.create(response); 1340 } catch (GenericEntityException e) { 1341 Debug.logError(e, module); 1342 return ServiceUtil.returnError("Unable to create PaymentGatewayResponse for failed service call!"); 1343 } 1344 1345 Debug.logInfo("Created PaymentGatewayResponse record for returned error", module); 1346 return ServiceUtil.returnSuccess(); 1347 } 1348 1349 private static boolean processResult(DispatchContext dctx, Map result, GenericValue userLogin, GenericValue paymentPreference) throws GeneralException { 1350 Boolean authResult = (Boolean ) result.get("authResult"); 1351 Boolean captureResult = (Boolean ) result.get("captureResult"); 1352 boolean resultPassed = false; 1353 String initialStatus = paymentPreference.getString("statusId"); 1354 String authServiceType = null; 1355 1356 if (authResult != null) { 1357 processAuthResult(dctx, result, userLogin, paymentPreference); 1358 resultPassed = authResult.booleanValue(); 1359 authServiceType = ("PAYMENT_NOT_AUTH".equals(initialStatus)) ? AUTH_SERVICE_TYPE : REAUTH_SERVICE_TYPE;; 1360 } 1361 if (captureResult != null) { 1362 processCaptureResult(dctx, result, userLogin, paymentPreference, authServiceType); 1363 if (!resultPassed) 1364 resultPassed = captureResult.booleanValue(); 1365 } 1366 return resultPassed; 1367 } 1368 1369 private static void processAuthResult(DispatchContext dctx, Map result, GenericValue userLogin, GenericValue paymentPreference) throws GeneralException { 1370 LocalDispatcher dispatcher = dctx.getDispatcher(); 1371 result.put("userLogin", userLogin); 1372 result.put("orderPaymentPreference", paymentPreference); 1373 ModelService model = dctx.getModelService("processAuthResult"); 1374 Map context = model.makeValid(result, ModelService.IN_PARAM); 1375 Map svcResp = null; 1376 try { 1377 svcResp = dispatcher.runSync("processAuthResult", context); 1378 } catch (GenericServiceException e) { 1379 Debug.logError(e, module); 1380 throw e; 1381 } 1382 if (svcResp != null && ServiceUtil.isError(svcResp)) { 1383 Debug.logError(ServiceUtil.getErrorMessage(svcResp), module); 1384 throw new GeneralException(ServiceUtil.getErrorMessage(svcResp)); 1385 } 1386 } 1387 1388 public static Map processAuthResult(DispatchContext dctx, Map context) { 1389 GenericDelegator delegator = dctx.getDelegator(); 1390 GenericValue paymentPreference = (GenericValue) context.get("orderPaymentPreference"); 1391 Boolean authResult = (Boolean ) context.get("authResult"); 1392 String authType = (String ) context.get("serviceTypeEnum"); 1393 String currencyUomId = (String ) context.get("currencyUomId"); 1394 1395 if (UtilValidate.isEmpty(authType)) { 1397 authType = ("PAYMENT_NOT_AUTH".equals(paymentPreference.getString("statusId"))) ? 1398 AUTH_SERVICE_TYPE : REAUTH_SERVICE_TYPE; 1399 } 1400 1401 String responseId = delegator.getNextSeqId("PaymentGatewayResponse"); 1403 GenericValue response = delegator.makeValue("PaymentGatewayResponse", null); 1404 response.set("paymentGatewayResponseId", responseId); 1405 response.set("paymentServiceTypeEnumId", authType); 1406 response.set("orderPaymentPreferenceId", paymentPreference.get("orderPaymentPreferenceId")); 1407 response.set("paymentMethodTypeId", paymentPreference.get("paymentMethodTypeId")); 1408 response.set("paymentMethodId", paymentPreference.get("paymentMethodId")); 1409 response.set("transCodeEnumId", "PGT_AUTHORIZE"); 1410 response.set("currencyUomId", currencyUomId); 1411 1412 response.set("gatewayAvsResult", context.get("avsCode")); 1414 response.set("gatewayScoreResult", context.get("scoreCode")); 1415 1416 response.set("amount", context.get("processAmount")); 1418 response.set("referenceNum", context.get("authRefNum")); 1419 response.set("altReference", context.get("authAltRefNum")); 1420 response.set("gatewayCode", context.get("authCode")); 1421 response.set("gatewayFlag", context.get("authFlag")); 1422 response.set("gatewayMessage", context.get("authMessage")); 1423 response.set("transactionDate", UtilDateTime.nowTimestamp()); 1424 try { 1425 delegator.create(response); 1426 } catch (GenericEntityException e) { 1427 Debug.logError(e, module); 1428 return ServiceUtil.returnError("Error creating response information"); 1429 } 1430 1431 List messages = (List ) context.get("internalRespMsgs"); 1433 if (messages != null && messages.size() > 0) { 1434 Iterator i = messages.iterator(); 1435 while (i.hasNext()) { 1436 GenericValue respMsg = delegator.makeValue("PaymentGatewayRespMsg", null); 1437 String respMsgId = delegator.getNextSeqId("PaymentGatewayRespMsg"); 1438 String message = (String ) i.next(); 1439 respMsg.set("paymentGatewayRespMsgId", respMsgId); 1440 respMsg.set("paymentGatewayResponseId", responseId); 1441 respMsg.set("pgrMessage", message); 1442 try { 1443 delegator.create(respMsg); 1444 } catch (GenericEntityException e) { 1445 Debug.logError(e, module); 1446 return ServiceUtil.returnError("Error creating response message information"); 1447 } 1448 } 1449 } 1450 1451 if (response.getDouble("amount").doubleValue() != ((Double ) context.get("processAmount")).doubleValue()) { 1452 Debug.logWarning("The authorized amount does not match the max amount : Response - " + response + " : result - " + context, module); 1453 } 1454 1455 if (context != null && authResult.booleanValue()) { 1457 paymentPreference.set("statusId", "PAYMENT_AUTHORIZED"); 1458 paymentPreference.set("securityCode", null); 1459 } else if (context != null && !authResult.booleanValue()) { 1460 paymentPreference.set("statusId", "PAYMENT_DECLINED"); 1461 } else { 1462 paymentPreference.set("statusId", "PAYMENT_ERROR"); 1463 } 1464 try { 1465 paymentPreference.store(); 1466 } catch (GenericEntityException e) { 1467 Debug.logError(e, module); 1468 return ServiceUtil.returnError("Error updating order payment preference information"); 1469 } 1470 1471 return ServiceUtil.returnSuccess(); 1472 } 1473 1474 private static GenericValue processAuthRetryResult(DispatchContext dctx, Map result, GenericValue userLogin, GenericValue paymentPreference) throws GeneralException { 1475 processAuthResult(dctx, result, userLogin, paymentPreference); 1476 return getAuthTransaction(paymentPreference); 1477 } 1478 1479 private static void processCaptureResult(DispatchContext dctx, Map result, GenericValue userLogin, GenericValue paymentPreference) throws GeneralException { 1480 processCaptureResult(dctx, result, userLogin, paymentPreference, null); 1481 } 1482 1483 private static void processCaptureResult(DispatchContext dctx, Map result, GenericValue userLogin, GenericValue paymentPreference, String authServiceType) throws GeneralException { 1484 LocalDispatcher dispatcher = dctx.getDispatcher(); 1485 Boolean captureResult = (Boolean ) result.get("captureResult"); 1486 Double amount = null; 1487 if (result.get("captureAmount") != null) { 1488 amount = (Double ) result.get("captureAmount"); 1489 } else if (result.get("processAmount") != null) { 1490 amount = (Double ) result.get("processAmount"); 1491 result.put("captureAmount", amount); 1492 } 1493 1494 if (amount == null) { 1495 throw new GeneralException("Unable to process null capture amount"); 1496 } 1497 1498 if (result != null && captureResult.booleanValue()) { 1499 result.put("orderPaymentPreference", paymentPreference); 1500 result.put("userLogin", userLogin); 1501 result.put("serviceTypeEnum", authServiceType); 1502 1503 ModelService model = dctx.getModelService("processCaptureResult"); 1504 Map context = model.makeValid(result, ModelService.IN_PARAM); 1505 Map capRes = null; 1506 try { 1507 capRes = dispatcher.runSync("processCaptureResult", context); 1508 } catch (GenericServiceException e) { 1509 Debug.logError(e, module); 1510 throw e; 1511 } 1512 if (capRes != null && ServiceUtil.isError(capRes)) { 1513 throw new GeneralException(ServiceUtil.getErrorMessage(capRes)); 1514 } 1515 } else if (result != null && !captureResult.booleanValue()) { 1516 OrderReadHelper orh = null; 1518 try { 1519 GenericValue orderHeader = paymentPreference.getRelatedOne("OrderHeader"); 1520 if (orderHeader != null) 1521 orh = new OrderReadHelper(orderHeader); 1522 } catch (GenericEntityException e) { 1523 Debug.logError(e, "Problems getting OrderHeader; cannot re-auth the payment", module); 1524 } 1525 1526 if (amount != null && (double) amount.doubleValue() == new Double (0.00).doubleValue()) { 1527 amount = paymentPreference.getDouble("maxAmount"); 1528 Debug.log("resetting payment amount from 0.00 to correctMax amount", module); 1529 } 1530 Debug.log("reauth with amount: " + amount, module); 1531 if (orh != null) { 1532 Map authPayRes = authPayment(dispatcher, userLogin, orh, paymentPreference, amount.doubleValue(), true); 1534 Debug.log("authPayRes: " + authPayRes, module); 1535 if (authPayRes != null) { 1536 Boolean authResp = (Boolean ) authPayRes.get("authResult"); 1537 Boolean capResp = (Boolean ) authPayRes.get("captureResult"); 1538 if (authResp != null) { 1539 GenericValue authTrans = processAuthRetryResult(dctx, authPayRes, userLogin, paymentPreference); 1540 1541 if (authResp.booleanValue()) { 1542 if (capResp != null && capResp.booleanValue()) { 1544 processCaptureResult(dctx, result, userLogin, paymentPreference); 1545 } else { 1546 Map capPayRes = capturePayment(dctx, userLogin, orh, paymentPreference, amount.doubleValue(), authTrans); 1548 if (capPayRes != null) { 1549 Boolean capPayResp = (Boolean ) capPayRes.get("captureResult"); 1550 if (capPayResp != null && capPayResp.booleanValue()) { 1551 processCaptureResult(dctx, capPayRes, userLogin, paymentPreference); 1553 } else { 1554 Debug.logError("Capture of authorized payment failed: " + paymentPreference, module); 1556 } 1557 } else { 1558 Debug.logError("Problems trying to capture payment (null result): " + paymentPreference, module); 1559 } 1560 } 1561 } else { 1562 Debug.logError("Payment authorization failed: " + paymentPreference, module); 1563 } 1564 } else { 1565 Debug.logError("Payment authorization failed (null result): " + paymentPreference, module); 1566 } 1567 } else { 1568 Debug.logError("Problems trying to re-authorize the payment (null result): " + paymentPreference, module); 1569 } 1570 } else { 1571 Debug.logError("Null OrderReadHelper cannot process", module); 1572 } 1573 } else { 1574 Debug.logError("Result pass is null, no capture available", module); 1575 } 1576 } 1577 1578 public static Map processCaptureResult(DispatchContext dctx, Map context) { 1579 GenericDelegator delegator = dctx.getDelegator(); 1580 LocalDispatcher dispatcher = dctx.getDispatcher(); 1581 1582 GenericValue paymentPreference = (GenericValue) context.get("orderPaymentPreference"); 1583 GenericValue userLogin = (GenericValue) context.get("userLogin"); 1584 String invoiceId = (String ) context.get("invoiceId"); 1585 String payTo = (String ) context.get("payToPartyId"); 1586 Double amount = (Double ) context.get("captureAmount"); 1587 String serviceType = (String ) context.get("serviceTypeEnum"); 1588 String currencyUomId = (String ) context.get("currencyUomId"); 1589 1590 if (UtilValidate.isEmpty(serviceType)) { 1591 serviceType = CAPTURE_SERVICE_TYPE; 1592 } 1593 1594 String responseId = delegator.getNextSeqId("PaymentGatewayResponse"); 1596 GenericValue response = delegator.makeValue("PaymentGatewayResponse", null); 1597 response.set("paymentGatewayResponseId", responseId); 1598 response.set("paymentServiceTypeEnumId", serviceType); 1599 response.set("orderPaymentPreferenceId", paymentPreference.get("orderPaymentPreferenceId")); 1600 response.set("paymentMethodTypeId", paymentPreference.get("paymentMethodTypeId")); 1601 response.set("paymentMethodId", paymentPreference.get("paymentMethodId")); 1602 response.set("transCodeEnumId", "PGT_CAPTURE"); 1603 response.set("currencyUomId", currencyUomId); 1604 if (context.get("authRefNum") != null) { 1605 response.set("subReference", context.get("authRefNum")); 1606 response.set("altReference", context.get("authAltRefNum")); 1607 } else { 1608 response.set("altReference", context.get("captureAltRefNum")); 1609 } 1610 1611 response.set("amount", amount); 1613 response.set("referenceNum", context.get("captureRefNum")); 1614 response.set("gatewayCode", context.get("captureCode")); 1615 response.set("gatewayFlag", context.get("captureFlag")); 1616 response.set("gatewayMessage", context.get("captureMessage")); 1617 response.set("transactionDate", UtilDateTime.nowTimestamp()); 1618 try { 1619 delegator.create(response); 1620 } catch (GenericEntityException e) { 1621 Debug.logError(e, module); 1622 return ServiceUtil.returnError("Error creating response information"); 1623 } 1624 1625 List messages = (List ) context.get("internalRespMsgs"); 1627 if (messages != null && messages.size() > 0) { 1628 Iterator i = messages.iterator(); 1629 while (i.hasNext()) { 1630 GenericValue respMsg = delegator.makeValue("PaymentGatewayRespMsg", null); 1631 String respMsgId = delegator.getNextSeqId("PaymentGatewayRespMsg"); 1632 String message = (String ) i.next(); 1633 respMsg.set("paymentGatewayRespMsgId", respMsgId); 1634 respMsg.set("paymentGatewayResponseId", responseId); 1635 respMsg.set("pgrMessage", message); 1636 try { 1637 delegator.create(respMsg); 1638 } catch (GenericEntityException e) { 1639 Debug.logError(e, module); 1640 return ServiceUtil.returnError("Error creating response message information"); 1641 } 1642 } 1643 } 1644 1645 GenericValue invoice = null; 1647 if (invoiceId != null) { 1648 try { 1649 invoice = delegator.findByPrimaryKey("Invoice", UtilMisc.toMap("invoiceId", invoiceId)); 1650 } catch (GenericEntityException e) { 1651 String message = "Failed to process capture result: Could not find invoice ["+invoiceId+"] due to entity error: " + e.getMessage(); 1652 Debug.logError(e, message, module); 1653 return ServiceUtil.returnError(message ); 1654 } 1655 } 1656 1657 String partyIdFrom = null; 1659 if (invoice != null) { 1660 partyIdFrom = invoice.getString("partyId"); 1662 } else { 1663 String orderId = paymentPreference.getString("orderId"); 1665 List orl = null; 1666 try { 1667 orl = delegator.findByAnd("OrderRole", UtilMisc.toMap("orderId", orderId, "roleTypeId", "BILL_TO_CUSTOMER")); 1668 } catch (GenericEntityException e) { 1669 Debug.logError(e, module); 1670 } 1671 if (orl.size() > 0) { 1672 GenericValue orderRole = EntityUtil.getFirst(orl); 1673 partyIdFrom = orderRole.getString("partyId"); 1674 } 1675 } 1676 1677 String partyIdTo = null; 1679 if (!UtilValidate.isEmpty(payTo)) { 1680 partyIdTo = payTo; 1682 } else if (invoice != null) { 1683 partyIdTo = invoice.getString("partyIdFrom"); 1685 } else { 1686 payTo = "Company"; 1688 Debug.logWarning("Using default value of [Company] for payTo on invoice [" + invoiceId + "] and orderPaymentPreference [" + 1689 paymentPreference.getString("orderPaymentPreferenceId") + "]", module); 1690 } 1691 1692 1693 Map paymentCtx = UtilMisc.toMap("paymentTypeId", "CUSTOMER_PAYMENT"); 1694 paymentCtx.put("paymentMethodTypeId", paymentPreference.get("paymentMethodTypeId")); 1695 paymentCtx.put("paymentMethodId", paymentPreference.get("paymentMethodId")); 1696 paymentCtx.put("paymentGatewayResponseId", responseId); 1697 paymentCtx.put("partyIdTo", partyIdTo); 1698 paymentCtx.put("partyIdFrom", partyIdFrom); 1699 paymentCtx.put("statusId", "PMNT_RECEIVED"); 1700 paymentCtx.put("paymentPreferenceId", paymentPreference.get("orderPaymentPreferenceId")); 1701 paymentCtx.put("amount", amount); 1702 paymentCtx.put("currencyUomId", currencyUomId); 1703 paymentCtx.put("userLogin", userLogin); 1704 paymentCtx.put("paymentRefNum", context.get("captureRefNum")); 1705 1706 Map payRes = null; 1707 try { 1708 payRes = dispatcher.runSync("createPayment", paymentCtx); 1709 } catch (GenericServiceException e) { 1710 Debug.logError(e, module); 1711 return ServiceUtil.returnError("Error creating payment record"); 1712 } 1713 if (payRes != null && ServiceUtil.isError(payRes)) { 1714 return ServiceUtil.returnError(ServiceUtil.getErrorMessage(payRes)); 1715 } 1716 1717 String paymentId = (String ) payRes.get("paymentId"); 1718 paymentPreference.set("statusId", "PAYMENT_SETTLED"); 1719 try { 1720 paymentPreference.store(); 1721 } catch (GenericEntityException e) { 1722 Debug.logError(e, module); 1723 } 1724 1725 if (invoiceId != null) { 1727 Debug.logInfo("Processing Invoice #" + invoiceId, module); 1728 Map paCtx = UtilMisc.toMap("paymentId", paymentId, "invoiceId", invoiceId); 1729 paCtx.put("amountApplied", context.get("captureAmount")); 1730 paCtx.put("userLogin", userLogin); 1731 Map paRes = null; 1732 try { 1733 paRes = dispatcher.runSync("createPaymentApplication", paCtx); 1734 } catch (GenericServiceException e) { 1735 Debug.logError(e, module); 1736 return ServiceUtil.returnError("Error creating invoice application"); 1737 } 1738 if (paRes != null && ServiceUtil.isError(paRes)) { 1739 return ServiceUtil.returnError(ServiceUtil.getErrorMessage(paRes)); 1740 } 1741 } 1742 1743 return ServiceUtil.returnSuccess(); 1744 } 1745 1746 public static Map refundPayment(DispatchContext dctx, Map context) { 1747 GenericDelegator delegator = dctx.getDelegator(); 1748 LocalDispatcher dispatcher = dctx.getDispatcher(); 1749 GenericValue userLogin = (GenericValue) context.get("userLogin"); 1750 1751 GenericValue paymentPref = (GenericValue) context.get("orderPaymentPreference"); 1752 Double refundAmount = (Double ) context.get("refundAmount"); 1753 1754 GenericValue orderHeader = null; 1755 try { 1756 orderHeader = paymentPref.getRelatedOne("OrderHeader"); 1757 } catch (GenericEntityException e) { 1758 Debug.logError(e, "Cannot get OrderHeader from OrderPaymentPreference", module); 1759 return ServiceUtil.returnError("Problems getting OrderHeader from OrderPaymentPreference: " + e.getMessage()); 1760 } 1761 1762 OrderReadHelper orh = new OrderReadHelper(orderHeader); 1763 1764 GenericValue paymentSettings = null; 1765 if (orderHeader != null) { 1766 paymentSettings = getPaymentSettings(orderHeader, paymentPref, REFUND_SERVICE_TYPE, false); 1767 } 1768 1769 if (paymentSettings != null) { 1770 String paymentConfig = paymentSettings.getString("paymentPropertiesPath"); 1771 String serviceName = paymentSettings.getString("paymentService"); 1772 if (serviceName != null) { 1773 Map serviceContext = new HashMap (); 1774 serviceContext.put("orderPaymentPreference", paymentPref); 1775 serviceContext.put("paymentConfig", paymentConfig); 1776 serviceContext.put("currency", orh.getCurrency()); 1777 1778 String payToPartyId = null; 1780 try { 1781 payToPartyId = getBillingInformation(orh, paymentPref, new HashMap ()); 1782 } catch (GenericEntityException e) { 1783 Debug.logError(e, "Problems getting billing information", module); 1784 return ServiceUtil.returnError("Problems getting billing information"); 1785 } 1786 1787 String currencyFormat = UtilProperties.getPropertyValue("general.properties", "currency.decimal.format", "##0.00"); 1789 DecimalFormat formatter = new DecimalFormat (currencyFormat); 1790 String amountString = formatter.format(refundAmount); 1791 Double processAmount = null; 1792 try { 1793 processAmount = new Double (formatter.parse(amountString).doubleValue()); 1794 } catch (ParseException e) { 1795 Debug.logError(e, "Problem parsing amount using DecimalFormat", module); 1796 return ServiceUtil.returnError("Refund processor problems; see logs"); 1797 } 1798 serviceContext.put("refundAmount", processAmount); 1799 serviceContext.put("userLogin", userLogin); 1800 1801 Map refundResponse = null; 1803 try { 1804 refundResponse = dispatcher.runSync(serviceName, serviceContext, TX_TIME, true); 1805 } catch (GenericServiceException e) { 1806 Debug.logError(e, "Problem refunding payment through processor", module); 1807 return ServiceUtil.returnError("Refund processor problems; see logs"); 1808 } 1809 if (ServiceUtil.isError(refundResponse)) { 1810 saveError(dispatcher, userLogin, paymentPref, refundResponse, "PRDS_PAY_REFUND", "PGT_REFUND"); 1811 return ServiceUtil.returnError(ServiceUtil.getErrorMessage(refundResponse)); 1812 } 1813 1814 1816 if (paymentConfig == null || paymentConfig.length() == 0) { 1818 paymentConfig = "payment.properties"; 1819 } 1820 String payFromPartyId = getPayToPartyId(orderHeader); 1821 1822 String responseId = delegator.getNextSeqId("PaymentGatewayResponse"); 1824 GenericValue response = delegator.makeValue("PaymentGatewayResponse", null); 1825 response.set("paymentGatewayResponseId", responseId); 1826 response.set("paymentServiceTypeEnumId", REFUND_SERVICE_TYPE); 1827 response.set("orderPaymentPreferenceId", paymentPref.get("orderPaymentPreferenceId")); 1828 response.set("paymentMethodTypeId", paymentPref.get("paymentMethodTypeId")); 1829 response.set("paymentMethodId", paymentPref.get("paymentMethodId")); 1830 response.set("transCodeEnumId", "PGT_REFUND"); 1831 1832 response.set("amount", refundResponse.get("refundAmount")); 1834 response.set("referenceNum", refundResponse.get("refundRefNum")); 1835 response.set("altReference", refundResponse.get("refundAltRefNum")); 1836 response.set("gatewayCode", refundResponse.get("refundCode")); 1837 response.set("gatewayFlag", refundResponse.get("refundFlag")); 1838 response.set("gatewayMessage", refundResponse.get("refundMessage")); 1839 response.set("transactionDate", UtilDateTime.nowTimestamp()); 1840 try { 1841 delegator.create(response); 1842 } catch (GenericEntityException e) { 1843 Debug.logError(e, module); 1844 return ServiceUtil.returnError("Unable to create PaymentGatewayResponse record"); 1845 } 1846 1847 List messages = (List ) refundResponse.get("internalRespMsgs"); 1849 if (messages != null && messages.size() > 0) { 1850 Iterator i = messages.iterator(); 1851 while (i.hasNext()) { 1852 GenericValue respMsg = delegator.makeValue("PaymentGatewayRespMsg", null); 1853 String respMsgId = delegator.getNextSeqId("PaymentGatewayRespMsg"); 1854 String message = (String ) i.next(); 1855 respMsg.set("paymentGatewayRespMsgId", respMsgId); 1856 respMsg.set("paymentGatewayResponseId", responseId); 1857 respMsg.set("pgrMessage", message); 1858 try { 1859 delegator.create(respMsg); 1860 } catch (GenericEntityException e) { 1861 Debug.logError(e, module); 1862 return ServiceUtil.returnError("Unable to create PaymentGatewayRespMsg record"); 1863 } 1864 } 1865 } 1866 1867 Boolean refundResult = (Boolean ) refundResponse.get("refundResult"); 1869 if (refundResult != null && refundResult.booleanValue()) { 1870 Map paymentCtx = UtilMisc.toMap("paymentTypeId", "CUSTOMER_REFUND"); 1872 paymentCtx.put("paymentMethodTypeId", paymentPref.get("paymentMethodTypeId")); 1873 paymentCtx.put("paymentMethodId", paymentPref.get("paymentMethodId")); 1874 paymentCtx.put("paymentGatewayResponseId", responseId); 1875 paymentCtx.put("partyIdTo", payToPartyId); 1876 paymentCtx.put("partyIdFrom", payFromPartyId); 1877 paymentCtx.put("statusId", "PMNT_SENT"); 1878 paymentCtx.put("paymentPreferenceId", paymentPref.get("orderPaymentPreferenceId")); 1879 paymentCtx.put("currencyUomId", orh.getCurrency()); 1880 paymentCtx.put("amount", refundResponse.get("refundAmount")); 1881 paymentCtx.put("userLogin", userLogin); 1882 paymentCtx.put("paymentRefNum", refundResponse.get("refundRefNum")); 1883 paymentCtx.put("comments", "Refund"); 1884 1885 String paymentId = null; 1886 try { 1887 Map payRes = dispatcher.runSync("createPayment", paymentCtx); 1888 if (ModelService.RESPOND_ERROR.equals(payRes.get(ModelService.RESPONSE_MESSAGE))) { 1889 return ServiceUtil.returnError((String ) payRes.get(ModelService.ERROR_MESSAGE)); 1890 } else { 1891 paymentId = (String ) payRes.get("paymentId"); 1892 } 1893 } catch (GenericServiceException e) { 1894 Debug.logError(e, "Problem creating Payment", module); 1895 return ServiceUtil.returnError("Problem creating Payment"); 1896 } 1897 1899 if (paymentId == null) { 1900 return ServiceUtil.returnError("Create payment failed"); 1901 } 1902 1903 Map result = ServiceUtil.returnSuccess(); 1904 result.put("paymentId", paymentId); 1905 return result; 1906 } else { 1907 return ServiceUtil.returnError("The refund failed"); 1908 } 1909 } else { 1910 return ServiceUtil.returnError("No refund service defined"); 1911 } 1912 } else { 1913 return ServiceUtil.returnError("No payment settings found"); 1914 } 1915 } 1916 1917 public static Map retryFailedOrderAuth(DispatchContext dctx, Map context) { 1918 GenericDelegator delegator = dctx.getDelegator(); 1919 LocalDispatcher dispatcher = dctx.getDispatcher(); 1920 String orderId = (String ) context.get("orderId"); 1921 GenericValue userLogin = (GenericValue) context.get("userLogin"); 1922 1923 GenericValue orderHeader = null; 1925 try { 1926 orderHeader = delegator.findByPrimaryKey("OrderHeader", UtilMisc.toMap("orderId", orderId)); 1927 } catch (GenericEntityException e) { 1928 Debug.logError(e, module); 1929 return ServiceUtil.returnError(e.getMessage()); 1930 } 1931 1932 if (orderHeader == null || orderHeader.get("statusId") == null) { 1934 return ServiceUtil.returnError("Invalid OrderHeader record for ID: " + orderId); 1935 } 1936 1937 if (!"ORDER_CREATED".equals(orderHeader.getString("statusId"))) { 1939 return ServiceUtil.returnSuccess(); 1941 } 1942 1943 Map serviceResult = null; 1945 try { 1946 serviceResult = dispatcher.runSync("authOrderPayments", UtilMisc.toMap("orderId", orderId, "userLogin", userLogin)); 1947 } catch (GenericServiceException e) { 1948 Debug.logError(e, module); 1949 return ServiceUtil.returnError(e.getMessage()); 1950 } 1951 if (ServiceUtil.isError(serviceResult)) { 1952 return ServiceUtil.returnError(ServiceUtil.getErrorMessage(serviceResult)); 1953 } 1954 1955 String authResp = (String ) serviceResult.get("processResult"); 1957 if (authResp == null) { 1958 authResp = "ERROR"; 1959 } 1960 1961 if ("ERROR".equals(authResp)) { 1962 Debug.logWarning("The payment processor had a failure in processing, will not modify any status", module); 1963 } else { 1964 if ("FAILED".equals(authResp)) { 1965 OrderChangeHelper.rejectOrder(dispatcher, userLogin, orderId); 1967 1968 } else if ("APPROVED".equals(authResp)) { 1969 OrderChangeHelper.approveOrder(dispatcher, userLogin, orderId); 1971 } 1972 } 1973 1974 Map result = ServiceUtil.returnSuccess(); 1975 result.put("processResult", authResp); 1976 1977 return result; 1978 } 1979 1980 public static Map retryFailedAuths(DispatchContext dctx, Map context) { 1981 GenericDelegator delegator = dctx.getDelegator(); 1982 LocalDispatcher dispatcher = dctx.getDispatcher(); 1983 GenericValue userLogin = (GenericValue) context.get("userLogin"); 1984 1985 List exprs = UtilMisc.toList(new EntityExpr("statusId", EntityOperator.EQUALS, "PAYMENT_NOT_AUTH"), 1987 new EntityExpr("processAttempt", EntityOperator.GREATER_THAN, new Long (0))); 1988 1989 EntityListIterator eli = null; 1990 try { 1991 eli = delegator.findListIteratorByCondition("OrderPaymentPreference", 1992 new EntityConditionList(exprs, EntityOperator.AND), null, UtilMisc.toList("orderId")); 1993 } catch (GenericEntityException e) { 1994 Debug.logError(e, module); 1995 } 1996 1997 List processList = new ArrayList (); 1998 if (eli != null) { 1999 Debug.logInfo("Processing failed order re-auth(s)", module); 2000 GenericValue value; 2001 while (((value = (GenericValue) eli.next()) != null)) { 2002 String orderId = value.getString("orderId"); 2003 if (!processList.contains(orderId)) { try { 2005 dispatcher.runAsync("retryFailedOrderAuth", UtilMisc.toMap("orderId", orderId, "userLogin", userLogin)); 2007 processList.add(orderId); 2008 } catch (GenericServiceException e) { 2009 Debug.logError(e, module); 2010 } 2011 } 2012 } 2013 2014 try { 2015 eli.close(); 2016 } catch (GenericEntityException e) { 2017 Debug.logError(e, module); 2018 } 2019 } 2020 2021 processList = null; 2022 return ServiceUtil.returnSuccess(); 2023 } 2024 2025 public static GenericValue getCaptureTransaction(GenericValue orderPaymentPreference) { 2026 GenericValue capTrans = null; 2027 try { 2028 List order = UtilMisc.toList("-transactionDate"); 2029 List transactions = orderPaymentPreference.getRelated("PaymentGatewayResponse", null, order); 2030 2031 List exprs = UtilMisc.toList(new EntityExpr("paymentServiceTypeEnumId", EntityOperator.EQUALS, "PRDS_PAY_CAPTURE")); 2032 2033 List capTransactions = EntityUtil.filterByAnd(transactions, exprs); 2034 2035 capTrans = EntityUtil.getFirst(capTransactions); 2036 } catch (GenericEntityException e) { 2037 Debug.logError(e, "ERROR: Problem getting capture information from PaymentGatewayResponse", module); 2038 } 2039 return capTrans; 2040 } 2041 2042 2048 public static GenericValue getAuthTransaction(GenericValue orderPaymentPreference) { 2049 GenericValue authTrans = null; 2050 try { 2051 List order = UtilMisc.toList("-transactionDate"); 2052 List transactions = orderPaymentPreference.getRelated("PaymentGatewayResponse", null, order); 2053 2054 List exprs = UtilMisc.toList(new EntityExpr("paymentServiceTypeEnumId", EntityOperator.EQUALS, "PRDS_PAY_AUTH"), 2055 new EntityExpr("paymentServiceTypeEnumId", EntityOperator.EQUALS, "PRDS_PAY_REAUTH")); 2056 2057 List authTransactions = EntityUtil.filterByOr(transactions, exprs); 2058 2059 authTrans = EntityUtil.getFirst(authTransactions); 2060 } catch (GenericEntityException e) { 2061 Debug.logError(e, "ERROR: Problem getting authorization information from PaymentGatewayResponse", module); 2062 } 2063 return authTrans; 2064 } 2065 2066 public static Timestamp getAuthTime(GenericValue orderPaymentPreference) { 2067 GenericValue authTrans = PaymentGatewayServices.getAuthTransaction(orderPaymentPreference); 2068 Timestamp authTime = null; 2069 2070 if (authTrans != null) { 2071 authTime = authTrans.getTimestamp("transactionDate"); 2072 } 2073 2074 return authTime; 2075 } 2076 2077 public static boolean checkAuthValidity(GenericValue orderPaymentPreference, String paymentConfig) { 2078 Timestamp authTime = PaymentGatewayServices.getAuthTime(orderPaymentPreference); 2079 if (authTime == null) { 2080 return false; 2081 } 2082 2083 GenericValue paymentMethod = null; 2084 try { 2085 paymentMethod = orderPaymentPreference.getRelatedOne("PaymentMethod"); 2086 } catch (GenericEntityException e) { 2087 Debug.logError(e, module); 2088 } 2089 2090 if (paymentMethod != null && paymentMethod.getString("paymentMethodTypeId").equals("CREDIT_CARD")) { 2091 GenericValue creditCard = null; 2092 try { 2093 creditCard = paymentMethod.getRelatedOne("CreditCard"); 2094 } catch (GenericEntityException e) { 2095 Debug.logError(e, module); 2096 } 2097 if (creditCard != null) { 2098 String cardType = creditCard.getString("cardType"); 2099 String reauthDays = null; 2100 if ("Discover".equals(cardType)) { 2102 reauthDays = UtilProperties.getPropertyValue(paymentConfig, "payment.general.reauth.disc.days", "90"); 2103 } else if ("AmericanExpress".equals(cardType)) { 2104 reauthDays = UtilProperties.getPropertyValue(paymentConfig, "payment.general.reauth.amex.days", "30"); 2105 } else if ("MasterCard".equals(cardType)) { 2106 reauthDays = UtilProperties.getPropertyValue(paymentConfig, "payment.general.reauth.mc.days", "30"); 2107 } else if ("Visa".equals(cardType)) { 2108 reauthDays = UtilProperties.getPropertyValue(paymentConfig, "payment.general.reauth.visa.days", "7"); 2109 } else { 2110 reauthDays = UtilProperties.getPropertyValue(paymentConfig, "payment.general.reauth.other.days", "7"); 2111 } 2112 2113 int days = 0; 2114 try { 2115 days = Integer.parseInt(reauthDays); 2116 } catch (Exception e) { 2117 Debug.logError(e, module); 2118 } 2119 2120 if (days > 0) { 2121 Calendar cal = Calendar.getInstance(); 2122 cal.setTimeInMillis(authTime.getTime()); 2123 cal.add(Calendar.DAY_OF_YEAR, days); 2124 Timestamp validTime = new Timestamp (cal.getTimeInMillis()); 2125 Timestamp nowTime = UtilDateTime.nowTimestamp(); 2126 if (nowTime.after(validTime)) { 2127 return false; 2128 } 2129 } 2130 } 2131 } 2132 2133 return true; 2134 } 2135 2136 public static Map processManualCcTx(DispatchContext dctx, Map context) { 2138 GenericValue userLogin = (GenericValue) context.get("userLogin"); 2139 LocalDispatcher dispatcher = dctx.getDispatcher(); 2140 GenericDelegator delegator = dctx.getDelegator(); 2141 Security security = dctx.getSecurity(); 2142 2143 if (!security.hasEntityPermission("MANUAL", "_PAYMENT", userLogin)) { 2145 Debug.logWarning("**** Security [" + (new Date ()).toString() + "]: " + userLogin.get("userLoginId") + " attempt to run manual payment transaction!", module); 2146 return ServiceUtil.returnError("You do not have permission for this transaction."); 2147 } 2148 2149 String paymentMethodTypeId = (String ) context.get("paymentMethodTypeId"); 2150 String productStoreId = (String ) context.get("productStoreId"); 2151 String transactionType = (String ) context.get("transactionType"); 2152 String referenceCode = (String ) context.get("referenceCode"); 2153 if (referenceCode == null) { 2154 referenceCode = new Long (System.currentTimeMillis()).toString(); 2155 } 2156 2157 if (!transactionType.equals("PRDS_PAY_CREDIT")) { 2159 return ServiceUtil.returnError("This transaction type is not yet supported."); 2160 } 2161 2162 Map requestContext = new HashMap (); 2164 String paymentService = null; 2165 String paymentConfig = null; 2166 2167 GenericValue paymentSettings = ProductStoreWorker.getProductStorePaymentSetting(delegator, productStoreId, paymentMethodTypeId, transactionType, false); 2169 if (paymentSettings == null) { 2170 return ServiceUtil.returnError("No valid payment settings found for : " + productStoreId + "/" + transactionType); 2171 } else { 2172 paymentConfig = paymentSettings.getString("paymentPropertiesPath"); 2173 paymentService = paymentSettings.getString("paymentService"); 2174 requestContext.put("paymentConfig", paymentConfig); 2175 } 2176 2177 if (paymentService == null || paymentConfig == null) { 2179 return ServiceUtil.returnError("Invalid product store payment settings"); 2180 } 2181 2182 if (paymentMethodTypeId.equals("CREDIT_CARD")) { 2183 GenericValue creditCard = delegator.makeValue("CreditCard", null); 2184 creditCard.setAllFields(context, true, null, null); 2185 if (creditCard.get("firstNameOnCard") == null || creditCard.get("lastNameOnCard") == null || creditCard.get("cardType") == null || creditCard.get("cardNumber") == null) { 2186 return ServiceUtil.returnError("Credit card is missing required fields."); 2187 } 2188 String expMonth = (String ) context.get("expMonth"); 2189 String expYear = (String ) context.get("expYear"); 2190 String expDate = expMonth + "/" + expYear; 2191 creditCard.set("expireDate", expDate); 2192 requestContext.put("creditCard", creditCard); 2193 requestContext.put("cardSecurityCode", context.get("cardSecurityCode")); 2194 2195 GenericValue billingAddress = delegator.makeValue("PostalAddress", null); 2196 billingAddress.setAllFields(context, true, null, null); 2197 if (billingAddress.get("address1") == null || billingAddress.get("city") == null || billingAddress.get("postalCode") == null) { 2198 return ServiceUtil.returnError("Credit card billing address is missing required fields."); 2199 } 2200 requestContext.put("billingAddress", billingAddress); 2201 2202 2210 2211 GenericValue billToEmail = delegator.makeValue("ContactMech", null); 2212 billToEmail.set("infoString", context.get("infoString")); 2213 if (billToEmail.get("infoString") == null) { 2214 return ServiceUtil.returnError("Email address field cannot be empty."); 2215 } 2216 requestContext.put("billToEmail", billToEmail); 2217 requestContext.put("referenceCode", referenceCode); 2218 String currency = UtilProperties.getPropertyValue("general.properties", "currency.uom.id.default", "USD"); 2219 requestContext.put("currency", currency); 2220 requestContext.put("creditAmount", context.get("amount")); } else { 2222 return ServiceUtil.returnError("Payment method type : " + paymentMethodTypeId + " is not yet implemented for manual transactions"); 2223 } 2224 2225 Map response = null; 2227 try { 2228 response = dispatcher.runSync(paymentService, requestContext, TX_TIME, true); 2229 } catch (GenericServiceException e) { 2230 Debug.logError(e, module); 2231 return ServiceUtil.returnError("Error calling service : " + paymentService + " / " + requestContext); 2232 } 2233 2234 if (ServiceUtil.isError(response)) { 2236 return ServiceUtil.returnError(ServiceUtil.makeErrorMessage(response, null, null, null, null)); 2237 } 2238 2239 String refNum = (String ) response.get("creditRefNum"); 2241 String code = (String ) response.get("creditCode"); 2242 String msg = (String ) response.get("creditMessage"); 2243 Map returnResults = ServiceUtil.returnSuccess("Transaction result [" + msg + "/" + code +"] Ref#: " + refNum); 2244 returnResults.put("referenceNum", refNum); 2245 return returnResults; 2246 } 2247 2248 2252 2255 public static Map testProcessor(DispatchContext dctx, Map context) { 2256 Map result = new HashMap (); 2257 Double processAmount = (Double ) context.get("processAmount"); 2258 2259 if (processAmount != null && processAmount.doubleValue() >= 100.00) 2260 result.put("authResult", new Boolean (true)); 2261 if (processAmount != null && processAmount.doubleValue() < 100.00) 2262 result.put("authResult", new Boolean (false)); 2263 result.put("customerRespMsgs", UtilMisc.toList("Sorry this processor requires at least a $100.00 purchase.")); 2264 if (processAmount == null) 2265 result.put("authResult", null); 2266 2267 long nowTime = new Date ().getTime(); 2268 String refNum = new Long (nowTime).toString(); 2269 2270 result.put("processAmount", context.get("processAmount")); 2271 result.put("authRefNum", refNum); 2272 result.put("authAltRefNum", refNum); 2273 result.put("authFlag", "X"); 2274 result.put("authMessage", "This is a test processor; no payments were captured or authorized."); 2275 result.put("internalRespMsgs", UtilMisc.toList("This is a test processor; no payments were captured or authorized.")); 2276 return result; 2277 } 2278 2279 2282 public static Map testProcessorWithCapture(DispatchContext dctx, Map context) { 2283 Map result = new HashMap (); 2284 Double processAmount = (Double ) context.get("processAmount"); 2285 2286 if (processAmount != null && processAmount.doubleValue() >= 100.00) 2287 result.put("authResult", new Boolean (true)); 2288 result.put("captureResult", new Boolean (true)); 2289 if (processAmount != null && processAmount.doubleValue() < 100.00) 2290 result.put("authResult", new Boolean (false)); 2291 result.put("captureResult", new Boolean (false)); 2292 result.put("customerRespMsgs", UtilMisc.toList("Sorry this processor requires at least a $100.00 purchase.")); 2293 if (processAmount == null) 2294 result.put("authResult", null); 2295 2296 long nowTime = new Date ().getTime(); 2297 String refNum = new Long (nowTime).toString(); 2298 2299 result.put("processAmount", context.get("processAmount")); 2300 result.put("authRefNum", refNum); 2301 result.put("authAltRefNum", refNum); 2302 result.put("captureRefNum", refNum); 2303 result.put("captureAltRefNum", refNum); 2304 result.put("authCode", "100"); 2305 result.put("captureCode", "200"); 2306 result.put("authFlag", "X"); 2307 result.put("authMessage", "This is a test processor; no payments were captured or authorized."); 2308 result.put("internalRespMsgs", UtilMisc.toList("This is a test processor; no payments were captured or authorized.")); 2309 return result; 2310 } 2311 2312 2315 public static Map alwaysApproveProcessor(DispatchContext dctx, Map context) { 2316 Map result = new HashMap (); 2317 long nowTime = new Date ().getTime(); 2318 Debug.logInfo("Test Processor Approving Credit Card", module); 2319 2320 result.put("authResult", new Boolean (true)); 2321 result.put("processAmount", context.get("processAmount")); 2322 result.put("authRefNum", new Long (nowTime).toString()); 2323 result.put("authAltRefNum", new Long (nowTime).toString()); 2324 result.put("authCode", "100"); 2325 result.put("authFlag", "A"); 2326 result.put("authMessage", "This is a test processor; no payments were captured or authorized."); 2327 return result; 2328 } 2329 2330 public static Map alwaysApproveWithCapture(DispatchContext dctx, Map context) { 2331 Map result = new HashMap (); 2332 long nowTime = new Date ().getTime(); 2333 String refNum = new Long (nowTime).toString(); 2334 Debug.logInfo("Test Processor Approving Credit Card with Capture", module); 2335 2336 result.put("authResult", new Boolean (true)); 2337 result.put("captureResult", new Boolean (true)); 2338 result.put("processAmount", context.get("processAmount")); 2339 result.put("authRefNum", refNum); 2340 result.put("authAltRefNum", refNum); 2341 result.put("captureRefNum", refNum); 2342 result.put("captureAltRefNum", refNum); 2343 result.put("authCode", "100"); 2344 result.put("captureCode", "200"); 2345 result.put("authFlag", "A"); 2346 result.put("authMessage", "This is a test processor; no payments were captured or authorized."); 2347 return result; 2348 } 2349 2350 2353 public static Map alwaysDeclineProcessor(DispatchContext dctx, Map context) { 2354 Map result = ServiceUtil.returnSuccess(); 2355 Double processAmount = (Double ) context.get("processAmount"); 2356 long nowTime = new Date ().getTime(); 2357 Debug.logInfo("Test Processor Declining Credit Card", module); 2358 2359 result.put("authResult", new Boolean (false)); 2360 result.put("processAmount", processAmount); 2361 result.put("authRefNum", new Long (nowTime).toString()); 2362 result.put("authAltRefNum", new Long (nowTime).toString()); 2363 result.put("authFlag", "D"); 2364 result.put("authMessage", "This is a test processor; no payments were captured or authorized"); 2365 return result; 2366 } 2367 2368 2371 public static Map alwaysFailProcessor(DispatchContext dctx, Map context) { 2372 return ServiceUtil.returnError("Unable to communicate with bla"); 2373 } 2374 2375 public static Map testRelease(DispatchContext dctx, Map context) { 2376 Map result = ServiceUtil.returnSuccess(); 2377 long nowTime = new Date ().getTime(); 2378 2379 result.put("releaseResult", new Boolean (true)); 2380 result.put("releaseAmount", context.get("releaseAmount")); 2381 result.put("releaseRefNum", new Long (nowTime).toString()); 2382 result.put("releaseAltRefNum", new Long (nowTime).toString()); 2383 result.put("releaseFlag", "U"); 2384 result.put("releaseMessage", "This is a test release; no authorizations exist"); 2385 return result; 2386 } 2387 2388 2391 public static Map testCapture(DispatchContext dctx, Map context) { 2392 Map result = ServiceUtil.returnSuccess(); 2393 long nowTime = new Date ().getTime(); 2394 Debug.logInfo("Test Capture Process", module); 2395 2396 result.put("captureResult", new Boolean (true)); 2397 result.put("captureAmount", context.get("captureAmount")); 2398 result.put("captureRefNum", new Long (nowTime).toString()); 2399 result.put("captureAltRefNum", new Long (nowTime).toString()); 2400 result.put("captureFlag", "C"); 2401 result.put("captureMessage", "This is a test capture; no money was transferred"); 2402 return result; 2403 } 2404 2405 public static Map testCaptureWithReAuth(DispatchContext dctx, Map context) { 2406 GenericValue orderPaymentPreference = (GenericValue) context.get("orderPaymentPreference"); 2407 GenericValue authTransaction = (GenericValue) context.get("authTrans"); 2408 Debug.logInfo("Test Capture with 2 minute delay failure/re-auth process", module); 2409 2410 if (authTransaction == null){ 2411 authTransaction = PaymentGatewayServices.getAuthTransaction(orderPaymentPreference); 2412 } 2413 2414 if (authTransaction == null) { 2415 return ServiceUtil.returnError("No authorization transaction found for the OrderPaymentPreference; cannot capture"); 2416 } 2417 Timestamp txStamp = authTransaction.getTimestamp("transactionDate"); 2418 Timestamp nowStamp = UtilDateTime.nowTimestamp(); 2419 2420 Map result = ServiceUtil.returnSuccess(); 2421 long nowTime = new Date ().getTime(); 2422 result.put("captureAmount", context.get("captureAmount")); 2423 result.put("captureRefNum", new Long (nowTime).toString()); 2424 2425 Calendar cal = Calendar.getInstance(); 2426 cal.setTimeInMillis(txStamp.getTime()); 2427 cal.add(Calendar.MINUTE, 2); 2428 Timestamp twoMinAfter = new Timestamp (cal.getTimeInMillis()); 2429 Debug.log("Re-Auth Capture Test : Tx Date - " + txStamp + " : 2 Min - " + twoMinAfter + " : Now - " + nowStamp, module); 2430 2431 if (nowStamp.after(twoMinAfter)) { 2432 result.put("captureResult", new Boolean (false)); 2433 } else { 2434 result.put("captureResult", new Boolean (true)); 2435 result.put("captureFlag", "C"); 2436 result.put("captureMessage", "This is a test capture; no money was transferred"); 2437 } 2438 2439 return result; 2440 } 2441 2442 2445 public static Map testRefund(DispatchContext dctx, Map context) { 2446 Map result = ServiceUtil.returnSuccess(); 2447 long nowTime = new Date ().getTime(); 2448 Debug.logInfo("Test Refund Process", module); 2449 2450 result.put("refundResult", new Boolean (true)); 2451 result.put("refundAmount", context.get("refundAmount")); 2452 result.put("refundRefNum", new Long (nowTime).toString()); 2453 result.put("refundFlag", "R"); 2454 result.put("refundMessage", "This is a test refund; no money was transferred"); 2455 return result; 2456 } 2457 2458 public static Map testRefundFailure(DispatchContext dctx, Map context) { 2459 Map result = ServiceUtil.returnSuccess(); 2460 long nowTime = new Date ().getTime(); 2461 Debug.logInfo("Test Refund Process", module); 2462 2463 result.put("refundResult", new Boolean (false)); 2464 result.put("refundAmount", context.get("refundAmount")); 2465 result.put("refundRefNum", new Long (nowTime).toString()); 2466 result.put("refundFlag", "R"); 2467 result.put("refundMessage", "This is a test refund failure; no money was transferred"); 2468 return result; 2469 } 2470 2471} 2472
| Popular Tags
|