Source Code Cross Referenced for PaymentGatewayServices.java in  » ERP-CRM-Financial » SourceTap-CRM » org » ofbiz » accounting » payment » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » ERP CRM Financial » SourceTap CRM » org.ofbiz.accounting.payment 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * $Id: PaymentGatewayServices.java,v 1.26 2004/01/22 17:47:24 ajzeneski Exp $
0003:         *
0004:         *  Copyright (c) 2002 The Open For Business Project - www.ofbiz.org
0005:         *
0006:         *  Permission is hereby granted, free of charge, to any person obtaining a
0007:         *  copy of this software and associated documentation files (the "Software"),
0008:         *  to deal in the Software without restriction, including without limitation
0009:         *  the rights to use, copy, modify, merge, publish, distribute, sublicense,
0010:         *  and/or sell copies of the Software, and to permit persons to whom the
0011:         *  Software is furnished to do so, subject to the following conditions:
0012:         *
0013:         *  The above copyright notice and this permission notice shall be included
0014:         *  in all copies or substantial portions of the Software.
0015:         *
0016:         *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
0017:         *  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
0018:         *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
0019:         *  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
0020:         *  CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
0021:         *  OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
0022:         *  THE USE OR OTHER DEALINGS IN THE SOFTWARE.
0023:         */
0024:        package org.ofbiz.accounting.payment;
0025:
0026:        import java.text.DecimalFormat;
0027:        import java.text.ParseException;
0028:        import java.util.ArrayList;
0029:        import java.util.Collection;
0030:        import java.util.Date;
0031:        import java.util.HashMap;
0032:        import java.util.Iterator;
0033:        import java.util.List;
0034:        import java.util.Map;
0035:
0036:        import org.ofbiz.accounting.invoice.InvoiceWorker;
0037:        import org.ofbiz.base.util.Debug;
0038:        import org.ofbiz.base.util.GeneralException;
0039:        import org.ofbiz.base.util.UtilDateTime;
0040:        import org.ofbiz.base.util.UtilMisc;
0041:        import org.ofbiz.base.util.UtilProperties;
0042:        import org.ofbiz.base.util.UtilValidate;
0043:        import org.ofbiz.entity.GenericDelegator;
0044:        import org.ofbiz.entity.GenericEntityException;
0045:        import org.ofbiz.entity.GenericValue;
0046:        import org.ofbiz.entity.condition.EntityCondition;
0047:        import org.ofbiz.entity.condition.EntityConditionList;
0048:        import org.ofbiz.entity.condition.EntityExpr;
0049:        import org.ofbiz.entity.condition.EntityJoinOperator;
0050:        import org.ofbiz.entity.condition.EntityOperator;
0051:        import org.ofbiz.entity.util.EntityUtil;
0052:        import org.ofbiz.order.order.OrderReadHelper;
0053:        import org.ofbiz.party.contact.ContactHelper;
0054:        import org.ofbiz.product.store.ProductStoreWorker;
0055:        import org.ofbiz.service.DispatchContext;
0056:        import org.ofbiz.service.GenericServiceException;
0057:        import org.ofbiz.service.LocalDispatcher;
0058:        import org.ofbiz.service.ModelService;
0059:        import org.ofbiz.service.ServiceUtil;
0060:        import org.ofbiz.security.Security;
0061:
0062:        /**
0063:         * PaymentGatewayServices
0064:         *
0065:         * @author     <a href="mailto:jaz@ofbiz.org">Andy Zeneski</a>
0066:         * @version    $Revision: 1.26 $
0067:         * @since      2.0
0068:         */
0069:        public class PaymentGatewayServices {
0070:
0071:            public static final String module = PaymentGatewayServices.class
0072:                    .getName();
0073:            public static final String AUTH_SERVICE_TYPE = "PRDS_PAY_AUTH";
0074:            public static final String REAUTH_SERVICE_TYPE = "PRDS_PAY_REAUTH";
0075:            public static final String RELEASE_SERVICE_TYPE = "PRDS_PAY_RELEASE";
0076:            public static final String CAPTURE_SERVICE_TYPE = "PRDS_PAY_CAPTURE";
0077:            public static final String REFUND_SERVICE_TYPE = "PRDS_PAY_REFUND";
0078:            public static final String CREDIT_SERVICE_TYPE = "PRDS_PAY_CREDIT";
0079:
0080:            /**
0081:             * Processes payments through service calls to the defined processing service for the ProductStore/PaymentMethodType
0082:             * @return APPROVED|FAILED|ERROR for complete processing of ALL payment methods.
0083:             */
0084:            public static Map authOrderPayments(DispatchContext dctx,
0085:                    Map context) {
0086:                GenericDelegator delegator = dctx.getDelegator();
0087:                LocalDispatcher dispatcher = dctx.getDispatcher();
0088:                GenericValue userLogin = (GenericValue) context
0089:                        .get("userLogin");
0090:                String orderId = (String) context.get("orderId");
0091:                Map result = new HashMap();
0092:
0093:                // get the order header and payment preferences
0094:                GenericValue orderHeader = null;
0095:                List paymentPrefs = null;
0096:
0097:                try {
0098:                    // get the OrderHeader
0099:                    orderHeader = delegator.findByPrimaryKey("OrderHeader",
0100:                            UtilMisc.toMap("orderId", orderId));
0101:
0102:                    // get the payments to auth
0103:                    Map lookupMap = UtilMisc.toMap("orderId", orderId,
0104:                            "statusId", "PAYMENT_NOT_AUTH");
0105:                    List orderList = UtilMisc.toList("maxAmount");
0106:                    paymentPrefs = delegator.findByAnd(
0107:                            "OrderPaymentPreference", lookupMap, orderList);
0108:                } catch (GenericEntityException gee) {
0109:                    Debug.logError(gee,
0110:                            "Problems getting the order information", module);
0111:                    result.put(ModelService.RESPONSE_MESSAGE,
0112:                            ModelService.RESPOND_ERROR);
0113:                    result.put(ModelService.ERROR_MESSAGE,
0114:                            "ERROR: Could not get order information ("
0115:                                    + gee.getMessage() + ").");
0116:                    return result;
0117:                }
0118:
0119:                // make sure we have a OrderHeader
0120:                if (orderHeader == null) {
0121:                    return ServiceUtil
0122:                            .returnError("Could not find OrderHeader with orderId: "
0123:                                    + orderId + "; not processing payments.");
0124:                }
0125:
0126:                // get the order amounts
0127:                String currencyFormat = UtilProperties.getPropertyValue(
0128:                        "general.properties", "currency.decimal.format",
0129:                        "##0.00");
0130:                OrderReadHelper orh = new OrderReadHelper(orderHeader);
0131:                DecimalFormat formatter = new DecimalFormat(currencyFormat);
0132:                String grandTotalString = formatter.format(orh
0133:                        .getOrderGrandTotal());
0134:                Double grandTotal = null;
0135:                try {
0136:                    grandTotal = new Double(formatter.parse(grandTotalString)
0137:                            .doubleValue());
0138:                } catch (ParseException e) {
0139:                    Debug
0140:                            .logError(
0141:                                    e,
0142:                                    "Problem getting parsed grand total amount",
0143:                                    module);
0144:                    return ServiceUtil
0145:                            .returnError("ERROR: Cannot parse grand total from formatted string; see logs");
0146:                }
0147:
0148:                double totalRemaining = grandTotal.doubleValue();
0149:
0150:                // loop through and auth each payment
0151:                List finished = new ArrayList();
0152:                List hadError = new ArrayList();
0153:                Iterator payments = paymentPrefs.iterator();
0154:                while (payments.hasNext()) {
0155:                    GenericValue paymentPref = (GenericValue) payments.next();
0156:                    boolean reAuth = false;
0157:
0158:                    // if we are already authorized, then this is a re-auth request
0159:                    if (paymentPref.get("statusId") != null
0160:                            && "PAYMENT_AUTHORIZED".equals(paymentPref
0161:                                    .getString("statusId"))) {
0162:                        reAuth = true;
0163:                    }
0164:
0165:                    // check the maxAmount for 0.00
0166:                    Double maxAmount = paymentPref.getDouble("maxAmount");
0167:                    if (maxAmount == null || maxAmount.doubleValue() > 0) {
0168:                        // call the authPayment method
0169:                        Map processorResult = authPayment(dispatcher,
0170:                                userLogin, orh, paymentPref, totalRemaining,
0171:                                reAuth);
0172:
0173:                        // handle the response
0174:                        if (processorResult != null) {
0175:                            // not null result means either an approval or decline; null would mean error
0176:                            GenericValue paymentSettings = (GenericValue) processorResult
0177:                                    .get("paymentSettings");
0178:                            Double this Amount = (Double) processorResult
0179:                                    .get("processAmount");
0180:
0181:                            // process the auth results
0182:                            boolean processResult = false;
0183:                            try {
0184:                                processResult = processResult(dctx,
0185:                                        processorResult, userLogin,
0186:                                        paymentPref, paymentSettings);
0187:                                if (processResult) {
0188:                                    totalRemaining -= this Amount.doubleValue();
0189:                                    finished.add(processorResult);
0190:                                }
0191:                            } catch (GeneralException e) {
0192:                                Debug.logError(e,
0193:                                        "Trouble processing the result; processorResult: "
0194:                                                + processorResult, module);
0195:                                hadError.add(paymentPref);
0196:                                ServiceUtil
0197:                                        .returnError("Trouble processing the auth results");
0198:                            }
0199:                        } else {
0200:                            // error with payment processor; will try later
0201:                            hadError.add(paymentPref);
0202:                            continue;
0203:                        }
0204:                    } else {
0205:                        Debug
0206:                                .logInfo(
0207:                                        "Invalid OrderPaymentPreference; maxAmount is 0",
0208:                                        module);
0209:                        paymentPref.set("statusId", "PAYMENT_CANCELLED");
0210:                        try {
0211:                            paymentPref.store();
0212:                        } catch (GenericEntityException e) {
0213:                            Debug
0214:                                    .logError(
0215:                                            e,
0216:                                            "ERROR: Problem setting OrderPaymentPreference status to CANCELLED",
0217:                                            module);
0218:                        }
0219:                        finished.add(null);
0220:                    }
0221:                }
0222:
0223:                Debug.logInfo("Finished with auth(s) checking results", module);
0224:
0225:                if (hadError.size() > 0) {
0226:                    Debug.logError("Error(s) (" + hadError.size()
0227:                            + ") during auth; returning ERROR", module);
0228:                    result.put(ModelService.RESPONSE_MESSAGE,
0229:                            ModelService.RESPOND_SUCCESS);
0230:                    result.put("processResult", "ERROR");
0231:                    return result;
0232:
0233:                } else if (finished.size() == paymentPrefs.size()) {
0234:                    Debug.logInfo("All auth(s) passed total remaining : "
0235:                            + totalRemaining, module);
0236:                    result.put(ModelService.RESPONSE_MESSAGE,
0237:                            ModelService.RESPOND_SUCCESS);
0238:                    result.put("processResult", "APPROVED");
0239:                    return result;
0240:                } else {
0241:                    Debug.logInfo("Only (" + finished.size()
0242:                            + ") passed auth; returning FAILED", module);
0243:                    result.put(ModelService.RESPONSE_MESSAGE,
0244:                            ModelService.RESPOND_SUCCESS);
0245:                    result.put("processResult", "FAILED");
0246:                    return result;
0247:                }
0248:            }
0249:
0250:            private static Map authPayment(LocalDispatcher dispatcher,
0251:                    GenericValue userLogin, OrderReadHelper orh,
0252:                    GenericValue paymentPref, double totalRemaining,
0253:                    boolean reauth) {
0254:                String paymentConfig = null;
0255:                String serviceName = null;
0256:
0257:                // get the payment settings i.e. serviceName and config properties file name
0258:                String serviceType = AUTH_SERVICE_TYPE;
0259:                if (reauth) {
0260:                    serviceType = REAUTH_SERVICE_TYPE;
0261:                }
0262:
0263:                GenericValue paymentSettings = getPaymentSettings(orh
0264:                        .getOrderHeader(), paymentPref, serviceType, false);
0265:                if (paymentSettings != null) {
0266:                    serviceName = paymentSettings.getString("paymentService");
0267:                    paymentConfig = paymentSettings
0268:                            .getString("paymentPropertiesPath");
0269:                } else {
0270:                    Debug
0271:                            .logError(
0272:                                    "Invalid payment settings entity, no payment settings found",
0273:                                    module);
0274:                    return null;
0275:                }
0276:
0277:                // make sure the service name is not null
0278:                if (serviceName == null) {
0279:                    Debug.logError("Invalid payment processor: + "
0280:                            + paymentSettings, module);
0281:                    return null;
0282:                }
0283:
0284:                // get the process context
0285:                Map processContext = null;
0286:                try {
0287:                    processContext = makeAuthContext(orh, userLogin,
0288:                            paymentPref, paymentConfig, totalRemaining);
0289:                } catch (GeneralException e) {
0290:                    Debug
0291:                            .logError(
0292:                                    e,
0293:                                    "Problems creating the context for the auth service",
0294:                                    module);
0295:                    return null;
0296:                }
0297:
0298:                // the amount of this transaction
0299:                Double this Amount = (Double) processContext
0300:                        .get("processAmount");
0301:
0302:                // invoke the processor.
0303:                Map processorResult = null;
0304:                try {
0305:                    processorResult = dispatcher.runSync(serviceName,
0306:                            processContext);
0307:                } catch (GenericServiceException gse) {
0308:                    Debug.logError("Error occurred on: " + serviceName + " => "
0309:                            + processContext, module);
0310:                    Debug.logError(gse,
0311:                            "Problems invoking payment processor! Will retry later."
0312:                                    + "(" + orh.getOrderId() + ")", module);
0313:                    return null;
0314:                }
0315:
0316:                if (processorResult != null) {
0317:                    // check for errors from the processor implementation
0318:                    String resultResponseCode = (String) processorResult
0319:                            .get(ModelService.RESPONSE_MESSAGE);
0320:                    if (resultResponseCode != null
0321:                            && resultResponseCode
0322:                                    .equals(ModelService.RESPOND_ERROR)) {
0323:                        Debug.logError("Processor failed; will retry later : "
0324:                                + processorResult
0325:                                        .get(ModelService.ERROR_MESSAGE),
0326:                                module);
0327:                        return null;
0328:                    }
0329:
0330:                    // pass the payTo partyId to the result processor; we just add it to the result context.
0331:                    String payToPartyId = getPayToPartyId(orh.getOrderHeader());
0332:                    processorResult.put("payToPartyId", payToPartyId);
0333:
0334:                    // add paymentSettings to result; for use by later processors
0335:                    processorResult.put("paymentSettings", paymentSettings);
0336:                }
0337:
0338:                return processorResult;
0339:            }
0340:
0341:            private static GenericValue getPaymentSettings(
0342:                    GenericValue orderHeader, GenericValue paymentPreference,
0343:                    String paymentServiceType, boolean anyServiceType) {
0344:                GenericDelegator delegator = orderHeader.getDelegator();
0345:                GenericValue paymentSettings = null;
0346:                GenericValue paymentMethod = null;
0347:                try {
0348:                    paymentMethod = paymentPreference
0349:                            .getRelatedOne("PaymentMethod");
0350:                } catch (GenericEntityException e) {
0351:                    Debug
0352:                            .logError(
0353:                                    e,
0354:                                    "Problem getting PaymentMethod from OrderPaymentPreference",
0355:                                    module);
0356:                }
0357:                if (paymentMethod != null) {
0358:                    String productStoreId = orderHeader
0359:                            .getString("productStoreId");
0360:                    String paymentMethodTypeId = paymentMethod
0361:                            .getString("paymentMethodTypeId");
0362:                    if (productStoreId != null && paymentMethodTypeId != null) {
0363:                        paymentSettings = ProductStoreWorker
0364:                                .getProductStorePaymentSetting(delegator,
0365:                                        productStoreId, paymentMethodTypeId,
0366:                                        paymentServiceType, anyServiceType);
0367:                    }
0368:                }
0369:                return paymentSettings;
0370:            }
0371:
0372:            private static String getPayToPartyId(GenericValue orderHeader) {
0373:                String payToPartyId = "Company"; // default value
0374:                GenericValue productStore = null;
0375:                try {
0376:                    productStore = orderHeader.getRelatedOne("ProductStore");
0377:                } catch (GenericEntityException e) {
0378:                    Debug.logError(e,
0379:                            "Unable to get ProductStore from OrderHeader",
0380:                            module);
0381:                    return null;
0382:                }
0383:                if (productStore != null
0384:                        && productStore.get("payToPartyId") != null) {
0385:                    payToPartyId = productStore.getString("payToPartyId");
0386:                }
0387:                return payToPartyId;
0388:            }
0389:
0390:            private static Map makeAuthContext(OrderReadHelper orh,
0391:                    GenericValue userLogin, GenericValue paymentPreference,
0392:                    String paymentConfig, double totalRemaining)
0393:                    throws GeneralException {
0394:                Map processContext = new HashMap();
0395:
0396:                processContext.put("userLogin", userLogin);
0397:                processContext.put("orderId", orh.getOrderId());
0398:                processContext.put("orderItems", orh.getOrderItems());
0399:                processContext.put("shippingAddress", orh.getShippingAddress());
0400:                processContext.put("paymentConfig", paymentConfig);
0401:                processContext.put("currency", orh.getCurrency());
0402:                processContext.put("orderPaymentPreference", paymentPreference);
0403:
0404:                // get the billing information
0405:                getBillingInformation(orh, paymentPreference, processContext);
0406:
0407:                // get the process amount
0408:                double this Amount = totalRemaining;
0409:                if (paymentPreference.get("maxAmount") != null) {
0410:                    this Amount = paymentPreference.getDouble("maxAmount")
0411:                            .doubleValue();
0412:                }
0413:
0414:                // don't authorized more then what is required
0415:                if (this Amount > totalRemaining) {
0416:                    this Amount = totalRemaining;
0417:                }
0418:
0419:                // format the decimal
0420:                String currencyFormat = UtilProperties.getPropertyValue(
0421:                        "general.properties", "currency.decimal.format",
0422:                        "##0.00");
0423:                DecimalFormat formatter = new DecimalFormat(currencyFormat);
0424:                String amountString = formatter.format(this Amount);
0425:                Double processAmount = null;
0426:                try {
0427:                    processAmount = new Double(formatter.parse(amountString)
0428:                            .doubleValue());
0429:                } catch (ParseException e) {
0430:                    Debug
0431:                            .logError(
0432:                                    e,
0433:                                    "Problems parsing string formatted double to Double",
0434:                                    module);
0435:                    throw new GeneralException(
0436:                            "ParseException in number format", e);
0437:                }
0438:
0439:                if (Debug.verboseOn())
0440:                    Debug.logVerbose("Charging amount: " + processAmount,
0441:                            module);
0442:                processContext.put("processAmount", processAmount);
0443:
0444:                return processContext;
0445:            }
0446:
0447:            private static String getBillingInformation(OrderReadHelper orh,
0448:                    GenericValue paymentPreference, Map toContext)
0449:                    throws GenericEntityException {
0450:                // gather the payment related objects.
0451:                GenericValue paymentMethod = paymentPreference
0452:                        .getRelatedOne("PaymentMethod");
0453:                if (paymentMethod != null
0454:                        && paymentMethod.getString("paymentMethodTypeId")
0455:                                .equals("CREDIT_CARD")) {
0456:                    // type credit card
0457:                    GenericValue creditCard = paymentMethod
0458:                            .getRelatedOne("CreditCard");
0459:                    GenericValue billingAddress = creditCard
0460:                            .getRelatedOne("PostalAddress");
0461:                    toContext.put("creditCard", creditCard);
0462:                    toContext.put("billingAddress", billingAddress);
0463:                } else if (paymentMethod != null
0464:                        && paymentMethod.getString("paymentMethodTypeId")
0465:                                .equals("EFT_ACCOUNT")) {
0466:                    // type eft
0467:                    GenericValue eftAccount = paymentMethod
0468:                            .getRelatedOne("EftAccount");
0469:                    GenericValue billingAddress = eftAccount
0470:                            .getRelatedOne("PostalAddress");
0471:                    toContext.put("eftAccount", eftAccount);
0472:                    toContext.put("billingAddress", billingAddress);
0473:                } else if (paymentMethod != null
0474:                        && paymentMethod.getString("paymentMethodTypeId")
0475:                                .equals("GIFT_CARD")) {
0476:                    // type gift card
0477:                    GenericValue giftCard = paymentMethod
0478:                            .getRelatedOne("GiftCard");
0479:                    toContext.put("giftCard", giftCard);
0480:                } else {
0481:                    // add other payment types here; i.e. gift cards, etc.
0482:                    // unknown payment type; ignoring.
0483:                    Debug
0484:                            .logError(
0485:                                    "ERROR: Unsupported PaymentMethodType passed for authorization",
0486:                                    module);
0487:                    return null;
0488:                }
0489:
0490:                // get some contact info.
0491:                GenericValue contactPerson = orh.getBillToPerson();
0492:                GenericValue contactEmail = null;
0493:                Collection emails = null;
0494:
0495:                try {
0496:                    emails = ContactHelper.getContactMech(contactPerson
0497:                            .getRelatedOne("Party"), "PRIMARY_EMAIL",
0498:                            "EMAIL_ADDRESS", false);
0499:                } catch (GenericEntityException gee) {
0500:                    Debug.logError("Problems getting contact information: "
0501:                            + gee.getMessage(), module);
0502:                }
0503:                if (emails != null && emails.size() > 0)
0504:                    contactEmail = (GenericValue) emails.iterator().next();
0505:
0506:                toContext.put("contactPerson", contactPerson);
0507:                toContext.put("contactEmail", contactEmail);
0508:
0509:                return contactPerson.getString("partyId");
0510:            }
0511:
0512:            /**
0513:             *
0514:             * Releases authorizations through service calls to the defined processing service for the ProductStore/PaymentMethodType
0515:             * @return COMPLETE|FAILED|ERROR for complete processing of ALL payments.
0516:             */
0517:            public static Map releaseOrderPayments(DispatchContext dctx,
0518:                    Map context) {
0519:                GenericDelegator delegator = dctx.getDelegator();
0520:                LocalDispatcher dispatcher = dctx.getDispatcher();
0521:                GenericValue userLogin = (GenericValue) context
0522:                        .get("userLogin");
0523:                String orderId = (String) context.get("orderId");
0524:
0525:                Map result = new HashMap();
0526:
0527:                // get the order header and payment preferences
0528:                GenericValue orderHeader = null;
0529:                List paymentPrefs = null;
0530:
0531:                try {
0532:                    // first get the order header
0533:                    orderHeader = delegator.findByPrimaryKey("OrderHeader",
0534:                            UtilMisc.toMap("orderId", orderId));
0535:                    // get the valid payment prefs
0536:                    List othExpr = UtilMisc.toList(new EntityExpr(
0537:                            "paymentMethodTypeId", EntityOperator.EQUALS,
0538:                            "EFT_ACCOUNT"));
0539:                    othExpr.add(new EntityExpr("paymentMethodTypeId",
0540:                            EntityOperator.EQUALS, "GIFT_CARD"));
0541:                    EntityCondition con1 = new EntityConditionList(othExpr,
0542:                            EntityJoinOperator.OR);
0543:
0544:                    EntityCondition statExpr = new EntityExpr("statusId",
0545:                            EntityOperator.EQUALS, "PAYMENT_SETTLED");
0546:                    EntityCondition con2 = new EntityConditionList(UtilMisc
0547:                            .toList(con1, statExpr), EntityOperator.AND);
0548:
0549:                    EntityCondition authExpr = new EntityExpr("statusId",
0550:                            EntityOperator.EQUALS, "PAYMENT_AUTHORIZED");
0551:                    EntityCondition con3 = new EntityConditionList(UtilMisc
0552:                            .toList(con2, authExpr), EntityOperator.OR);
0553:
0554:                    EntityExpr orderExpr = new EntityExpr("orderId",
0555:                            EntityOperator.EQUALS, orderId);
0556:                    EntityCondition con4 = new EntityConditionList(UtilMisc
0557:                            .toList(con3, orderExpr), EntityOperator.AND);
0558:
0559:                    paymentPrefs = delegator.findByCondition(
0560:                            "OrderPaymentPreference", con4, null, null);
0561:                } catch (GenericEntityException gee) {
0562:                    Debug
0563:                            .logError(
0564:                                    gee,
0565:                                    "Problems getting entity record(s), see stack trace",
0566:                                    module);
0567:                    result.put(ModelService.RESPONSE_MESSAGE,
0568:                            ModelService.RESPOND_ERROR);
0569:                    result.put(ModelService.ERROR_MESSAGE,
0570:                            "ERROR: Could not get order information ("
0571:                                    + gee.getMessage() + ").");
0572:                    return result;
0573:                }
0574:
0575:                // error if no order was found
0576:                if (orderHeader == null) {
0577:                    return ServiceUtil
0578:                            .returnError("Could not find OrderHeader with orderId: "
0579:                                    + orderId + "; not processing payments.");
0580:                }
0581:
0582:                // return complete if no payment prefs were found
0583:                if (paymentPrefs == null || paymentPrefs.size() == 0) {
0584:                    Debug
0585:                            .logWarning(
0586:                                    "No OrderPaymentPreference records available for release",
0587:                                    module);
0588:                    result.put("processResult", "COMPLETE");
0589:                    result.put(ModelService.RESPONSE_MESSAGE,
0590:                            ModelService.RESPOND_SUCCESS);
0591:                    return result;
0592:                }
0593:
0594:                OrderReadHelper orh = new OrderReadHelper(orderHeader);
0595:                String currency = orh.getCurrency();
0596:
0597:                // iterate over the prefs and release each one
0598:                List finished = new ArrayList();
0599:                Iterator payments = paymentPrefs.iterator();
0600:                while (payments.hasNext()) {
0601:                    GenericValue paymentPref = (GenericValue) payments.next();
0602:
0603:                    // look up the payment configuration settings
0604:                    String serviceName = null;
0605:                    String paymentConfig = null;
0606:
0607:                    // get the payment settings i.e. serviceName and config properties file name
0608:                    GenericValue paymentSettings = getPaymentSettings(orh
0609:                            .getOrderHeader(), paymentPref,
0610:                            RELEASE_SERVICE_TYPE, false);
0611:                    if (paymentSettings != null) {
0612:                        paymentConfig = paymentSettings
0613:                                .getString("paymentPropertiesPath");
0614:                        serviceName = paymentSettings
0615:                                .getString("paymentService");
0616:                        if (serviceName == null) {
0617:                            Debug.logError(
0618:                                    "Service name is null for payment setting; cannot process for : "
0619:                                            + paymentPref, module);
0620:                        }
0621:                    } else {
0622:                        Debug.logError(
0623:                                "Invalid payment settings entity, no payment release settings found for : "
0624:                                        + paymentPref, module);
0625:                        continue; // no release service available -- has been logged
0626:                    }
0627:
0628:                    if (paymentConfig == null || paymentConfig.length() == 0) {
0629:                        paymentConfig = "payment.properties";
0630:                    }
0631:
0632:                    GenericValue authTransaction = PaymentGatewayServices
0633:                            .getAuthTransaction(paymentPref);
0634:                    Map releaseContext = new HashMap();
0635:                    releaseContext.put("orderPaymentPreference", paymentPref);
0636:                    releaseContext.put("releaseAmount", authTransaction
0637:                            .getDouble("amount"));
0638:                    releaseContext.put("currency", currency);
0639:                    releaseContext.put("paymentConfig", paymentConfig);
0640:                    releaseContext.put("userLogin", userLogin);
0641:
0642:                    // run the defined service
0643:                    Map releaseResult = null;
0644:                    try {
0645:                        releaseResult = dispatcher.runSync(serviceName,
0646:                                releaseContext);
0647:                    } catch (GenericServiceException e) {
0648:                        Debug.logError(e, "Problem releasing payment", module);
0649:                    }
0650:
0651:                    // get the release result code
0652:                    Boolean releaseResponse = (Boolean) releaseResult
0653:                            .get("releaseResult");
0654:
0655:                    // create the PaymentGatewayResponse
0656:                    String responseId = delegator.getNextSeqId(
0657:                            "PaymentGatewayResponse").toString();
0658:                    GenericValue pgResponse = delegator.makeValue(
0659:                            "PaymentGatewayResponse", null);
0660:                    pgResponse.set("paymentGatewayResponseId", responseId);
0661:                    pgResponse.set("paymentServiceTypeEnumId",
0662:                            RELEASE_SERVICE_TYPE);
0663:                    pgResponse.set("orderPaymentPreferenceId", paymentPref
0664:                            .get("orderPaymentPreferenceId"));
0665:                    pgResponse.set("paymentMethodTypeId", paymentPref
0666:                            .get("paymentMethodTypeId"));
0667:                    pgResponse.set("paymentMethodId", paymentPref
0668:                            .get("paymentMethodId"));
0669:
0670:                    // set the auth info
0671:                    pgResponse.set("referenceNum", releaseResult
0672:                            .get("releaseRefNum"));
0673:                    pgResponse.set("gatewayCode", releaseResult
0674:                            .get("releaseCode"));
0675:                    pgResponse.set("gatewayFlag", releaseResult
0676:                            .get("releaseFlag"));
0677:                    pgResponse.set("gatewayMessage", releaseResult
0678:                            .get("releaseMessage"));
0679:                    pgResponse.set("transactionDate", UtilDateTime
0680:                            .nowTimestamp());
0681:
0682:                    // store the gateway response
0683:                    try {
0684:                        pgResponse.create();
0685:                    } catch (GenericEntityException e) {
0686:                        Debug.logError(e,
0687:                                "Problem storing PaymentGatewayResponse entity; authorization was released! : "
0688:                                        + pgResponse, module);
0689:                    }
0690:
0691:                    if (releaseResponse != null
0692:                            && releaseResponse.booleanValue()) {
0693:                        paymentPref.set("statusId", "PAYMENT_CANCELLED");
0694:                        try {
0695:                            paymentPref.store();
0696:                        } catch (GenericEntityException e) {
0697:                            Debug
0698:                                    .logError(
0699:                                            e,
0700:                                            "Problem storing updated payment preference; authorization was released!",
0701:                                            module);
0702:                        }
0703:                        finished.add(paymentPref);
0704:
0705:                        // cancel any payment records
0706:                        List paymentList = null;
0707:                        try {
0708:                            paymentList = paymentPref.getRelated("Payment");
0709:                        } catch (GenericEntityException e) {
0710:                            Debug.logError(e,
0711:                                    "Unable to get Payment records from OrderPaymentPreference : "
0712:                                            + paymentPref, module);
0713:                        }
0714:
0715:                        if (paymentList != null) {
0716:                            Iterator pi = paymentList.iterator();
0717:                            while (pi.hasNext()) {
0718:                                GenericValue pay = (GenericValue) pi.next();
0719:                                pay.set("statusId", "PMNT_CANCELLED");
0720:                                try {
0721:                                    pay.store();
0722:                                } catch (GenericEntityException e) {
0723:                                    Debug.logError(e,
0724:                                            "Unable to store Payment : " + pay,
0725:                                            module);
0726:                                }
0727:                            }
0728:                        }
0729:                    } else {
0730:                        Debug.logError("Release failed for pref : "
0731:                                + paymentPref, module);
0732:                    }
0733:                }
0734:
0735:                result = ServiceUtil.returnSuccess();
0736:                if (finished.size() == paymentPrefs.size()) {
0737:                    result.put("processResult", "COMPLETE");
0738:                } else {
0739:                    result.put("processResult", "FAILED");
0740:                }
0741:
0742:                return result;
0743:            }
0744:
0745:            /**
0746:             * Captures payments through service calls to the defined processing service for the ProductStore/PaymentMethodType
0747:             * @return COMPLETE|FAILED|ERROR for complete processing of ALL payment methods.
0748:             */
0749:            public static Map capturePaymentsByInvoice(DispatchContext dctx,
0750:                    Map context) {
0751:                GenericDelegator delegator = dctx.getDelegator();
0752:                LocalDispatcher dispatcher = dctx.getDispatcher();
0753:                GenericValue userLogin = (GenericValue) context
0754:                        .get("userLogin");
0755:                String invoiceId = (String) context.get("invoiceId");
0756:
0757:                // lookup the invoice
0758:                GenericValue invoice = null;
0759:                try {
0760:                    invoice = delegator.findByPrimaryKey("Invoice", UtilMisc
0761:                            .toMap("invoiceId", invoiceId));
0762:                } catch (GenericEntityException e) {
0763:                    Debug.logError(e, "Trouble looking up Invoice #"
0764:                            + invoiceId, module);
0765:                    return ServiceUtil
0766:                            .returnError("Trouble looking up Invoice #"
0767:                                    + invoiceId);
0768:                }
0769:
0770:                if (invoice == null) {
0771:                    Debug.logError("Could not locate invoice #" + invoiceId,
0772:                            module);
0773:                    return ServiceUtil.returnError("Could not locate invoice #"
0774:                            + invoiceId);
0775:                }
0776:
0777:                // get the OrderItemBilling records for this invoice
0778:                List orderItemBillings = null;
0779:                try {
0780:                    orderItemBillings = invoice.getRelated("OrderItemBilling");
0781:                } catch (GenericEntityException e) {
0782:                    Debug.logError(
0783:                            "Trouble getting OrderItemBilling(s) from Invoice #"
0784:                                    + invoiceId, module);
0785:                    return ServiceUtil
0786:                            .returnError("Trouble getting OrderItemBilling(s) from Invoice #"
0787:                                    + invoiceId);
0788:                }
0789:
0790:                // check for an associated billing account
0791:                String billingAccountId = invoice.getString("billingAccountId");
0792:
0793:                // make sure they are all for the same order
0794:                String testOrderId = null;
0795:                boolean allSameOrder = true;
0796:                if (orderItemBillings != null) {
0797:                    Iterator oii = orderItemBillings.iterator();
0798:                    while (oii.hasNext()) {
0799:                        GenericValue oib = (GenericValue) oii.next();
0800:                        String orderId = oib.getString("orderId");
0801:                        if (testOrderId == null) {
0802:                            testOrderId = orderId;
0803:                        } else {
0804:                            if (!orderId.equals(testOrderId)) {
0805:                                allSameOrder = false;
0806:                                break;
0807:                            }
0808:                        }
0809:                    }
0810:                }
0811:
0812:                if (testOrderId == null || !allSameOrder) {
0813:                    Debug.logWarning("Attempt to settle Invoice #" + invoiceId
0814:                            + " which contained none/multiple orders", module);
0815:                    return ServiceUtil.returnSuccess();
0816:                }
0817:
0818:                // get the invoice amount (amount to bill)
0819:                double invoiceTotal = InvoiceWorker.getInvoiceTotal(invoice);
0820:                //Debug.logInfo("Invoice total: " + invoiceTotal, module);
0821:
0822:                // now capture the order
0823:                Map serviceContext = UtilMisc.toMap("userLogin", userLogin,
0824:                        "orderId", testOrderId, "invoiceId", invoiceId,
0825:                        "captureAmount", new Double(invoiceTotal));
0826:                if (UtilValidate.isNotEmpty(billingAccountId)) {
0827:                    serviceContext.put("billingAccountId", billingAccountId);
0828:                }
0829:                try {
0830:                    return dispatcher.runSync("captureOrderPayments",
0831:                            serviceContext);
0832:                } catch (GenericServiceException e) {
0833:                    Debug.logError(e,
0834:                            "Trouble running captureOrderPayments service",
0835:                            module);
0836:                    return ServiceUtil
0837:                            .returnError("Trouble running captureOrderPayments service");
0838:                }
0839:            }
0840:
0841:            /**
0842:             * Captures payments through service calls to the defined processing service for the ProductStore/PaymentMethodType
0843:             * @return COMPLETE|FAILED|ERROR for complete processing of ALL payment methods.
0844:             */
0845:            public static Map captureOrderPayments(DispatchContext dctx,
0846:                    Map context) {
0847:                GenericDelegator delegator = dctx.getDelegator();
0848:                LocalDispatcher dispatcher = dctx.getDispatcher();
0849:                GenericValue userLogin = (GenericValue) context
0850:                        .get("userLogin");
0851:                String orderId = (String) context.get("orderId");
0852:                String invoiceId = (String) context.get("invoiceId");
0853:                String billingAccountId = (String) context
0854:                        .get("billingAccountId");
0855:                Double captureAmount = (Double) context.get("captureAmount");
0856:
0857:                Map result = new HashMap();
0858:
0859:                // get the order header and payment preferences
0860:                GenericValue orderHeader = null;
0861:                List paymentPrefs = null;
0862:
0863:                try {
0864:                    orderHeader = delegator.findByPrimaryKey("OrderHeader",
0865:                            UtilMisc.toMap("orderId", orderId));
0866:
0867:                    // get the payment prefs
0868:                    Map lookupMap = UtilMisc.toMap("orderId", orderId,
0869:                            "statusId", "PAYMENT_AUTHORIZED");
0870:                    List orderList = UtilMisc.toList("-authAmount");
0871:                    paymentPrefs = delegator.findByAnd(
0872:                            "OrderPaymentPreference", lookupMap, orderList);
0873:                } catch (GenericEntityException gee) {
0874:                    Debug
0875:                            .logError(
0876:                                    gee,
0877:                                    "Problems getting entity record(s), see stack trace",
0878:                                    module);
0879:                    result.put(ModelService.RESPONSE_MESSAGE,
0880:                            ModelService.RESPOND_ERROR);
0881:                    result.put(ModelService.ERROR_MESSAGE,
0882:                            "ERROR: Could not get order information ("
0883:                                    + gee.getMessage() + ").");
0884:                    return result;
0885:                }
0886:
0887:                // error if no order was found
0888:                if (orderHeader == null) {
0889:                    return ServiceUtil
0890:                            .returnError("Could not find OrderHeader with orderId: "
0891:                                    + orderId + "; not processing payments.");
0892:                }
0893:
0894:                // return complete if no payment prefs were found
0895:                if (paymentPrefs == null || paymentPrefs.size() == 0) {
0896:                    Debug.logWarning(
0897:                            "No orderPaymentPreferences available to capture",
0898:                            module);
0899:                    result.put("processResult", "COMPLETE");
0900:                    result.put(ModelService.RESPONSE_MESSAGE,
0901:                            ModelService.RESPOND_SUCCESS);
0902:                    return result;
0903:                }
0904:
0905:                OrderReadHelper orh = new OrderReadHelper(orderHeader);
0906:                double orderTotal = orh.getOrderGrandTotal();
0907:                double totalPayments = PaymentWorker.getPaymentsTotal(orh
0908:                        .getOrderPayments());
0909:                double remainingTotal = orderTotal - totalPayments;
0910:                Debug.logInfo("Remaining Total: " + remainingTotal, module);
0911:
0912:                // re-format the remaining total
0913:                String currencyFormat = UtilProperties.getPropertyValue(
0914:                        "general.properties", "currency.decimal.format",
0915:                        "##0.00");
0916:                DecimalFormat formatter = new DecimalFormat(currencyFormat);
0917:                String remainingTotalString = formatter.format(remainingTotal);
0918:                try {
0919:                    Number remaining = formatter.parse(remainingTotalString);
0920:                    if (remaining != null) {
0921:                        remainingTotal = remaining.doubleValue();
0922:                    }
0923:                } catch (ParseException e) {
0924:                    Debug.logError(e, "Problem getting parsed remaining total",
0925:                            module);
0926:                    return ServiceUtil
0927:                            .returnError("ERROR: Cannot parse grand total from formatted string; see logs");
0928:                }
0929:
0930:                if (captureAmount == null) {
0931:                    captureAmount = new Double(remainingTotal);
0932:                }
0933:                //Debug.logInfo("Formatted Remaining total : " + remainingTotal, module);
0934:
0935:                double amountToCapture = captureAmount.doubleValue();
0936:                //Debug.logInfo("Expected Capture Amount : " + amountToCapture, module);
0937:
0938:                // if we have a billing account get balance/limit and available
0939:                GenericValue billingAccount = null;
0940:                Double billingAccountBalance = null;
0941:                Double billingAccountAvail = null;
0942:                Map billingAccountInfo = null;
0943:                if (UtilValidate.isNotEmpty(billingAccountId)) {
0944:                    try {
0945:                        billingAccountInfo = dispatcher.runSync(
0946:                                "calcBillingAccountBalance", UtilMisc.toMap(
0947:                                        "billingAccountId", billingAccountId));
0948:                    } catch (GenericServiceException e) {
0949:                        Debug.logError(e,
0950:                                "Unable to get billing account information for #"
0951:                                        + billingAccountId, module);
0952:                    }
0953:                }
0954:                if (billingAccountInfo != null) {
0955:                    billingAccount = (GenericValue) billingAccountInfo
0956:                            .get("billingAccount");
0957:                    billingAccountBalance = (Double) billingAccountInfo
0958:                            .get("accountBalance");
0959:                }
0960:                if (billingAccount != null && billingAccountBalance != null) {
0961:                    Double accountLimit = billingAccount
0962:                            .getDouble("accountLimit");
0963:                    if (accountLimit == null) {
0964:                        accountLimit = new Double(0.00);
0965:                    }
0966:                    billingAccountAvail = new Double(accountLimit.doubleValue()
0967:                            - billingAccountBalance.doubleValue());
0968:                }
0969:
0970:                // iterate over the prefs and capture each one until we meet our total
0971:                List finished = new ArrayList();
0972:                Iterator payments = paymentPrefs.iterator();
0973:                while (payments.hasNext()) {
0974:                    GenericValue paymentPref = (GenericValue) payments.next();
0975:                    GenericValue authTrans = getAuthTransaction(paymentPref);
0976:                    if (authTrans == null) {
0977:                        continue;
0978:                    }
0979:
0980:                    Double authAmount = authTrans.getDouble("amount");
0981:                    if (authAmount == null)
0982:                        authAmount = new Double(0.00);
0983:                    if (authAmount.doubleValue() == 0.00) {
0984:                        // nothing to capture
0985:                        Debug.logInfo("Nothing to capture; authAmount = 0",
0986:                                module);
0987:                        continue;
0988:                    }
0989:                    //Debug.log("Actual Auth amount : " + authAmount, module);
0990:
0991:                    // if the authAmount is more then the remaining total; just use remaining total
0992:                    if (authAmount.doubleValue() > remainingTotal) {
0993:                        authAmount = new Double(remainingTotal);
0994:                    }
0995:
0996:                    // if we have a billing account; total up auth + account available
0997:                    double amountToBillAccount = 0.00;
0998:                    if (billingAccountAvail != null) {
0999:                        amountToBillAccount = authAmount.doubleValue()
1000:                                + billingAccountAvail.doubleValue();
1001:                    }
1002:
1003:                    // the amount for *this* capture
1004:                    double amountThisCapture = 0.00;
1005:
1006:                    // determine how much for *this* capture
1007:                    if (authAmount.doubleValue() >= amountToCapture) {
1008:                        // if the auth amount is more then expected capture just capture what is expected
1009:                        amountThisCapture = amountToCapture;
1010:                    } else if (payments.hasNext()) {
1011:                        // if we have more payments to capture; just capture what was authorized
1012:                        amountThisCapture = authAmount.doubleValue();
1013:                    } else if (billingAccountAvail != null
1014:                            && amountToBillAccount >= amountToCapture) {
1015:                        // the provided billing account will cover the remaining; just capture what was autorized
1016:                        amountThisCapture = authAmount.doubleValue();
1017:                    } else {
1018:                        // we need to capture more then what was authorized; re-auth for the new amount
1019:                        // TODO: add what the billing account cannot support to the re-auth amount
1020:                        // TODO: add support for re-auth for additional funds
1021:                        // just in case; we will capture the authorized amount here; until this is implemented
1022:                        Debug
1023:                                .logError(
1024:                                        "The amount to capture was more then what was authorized; we only captured the authorized amount : "
1025:                                                + paymentPref, module);
1026:                        amountThisCapture = authAmount.doubleValue();
1027:                    }
1028:
1029:                    Map captureResult = capturePayment(dispatcher, userLogin,
1030:                            orh, paymentPref, amountThisCapture);
1031:                    if (captureResult != null) {
1032:                        GenericValue paymentSettings = (GenericValue) captureResult
1033:                                .get("paymentSettings");
1034:                        Double amountCaptured = (Double) captureResult
1035:                                .get("captureAmount");
1036:                        if (amountCaptured != null)
1037:                            amountToCapture -= amountCaptured.doubleValue();
1038:                        finished.add(captureResult);
1039:
1040:                        // add the invoiceId to the result for processing
1041:                        captureResult.put("invoiceId", invoiceId);
1042:
1043:                        //Debug.log("Capture result : " + captureResult, module);
1044:
1045:                        // process the capture's results
1046:                        boolean processResult = false;
1047:                        try {
1048:                            processResult = processResult(dctx, captureResult,
1049:                                    userLogin, paymentPref, paymentSettings);
1050:                        } catch (GeneralException e) {
1051:                            Debug.logError(e,
1052:                                    "Trouble processing the result; captureResult: "
1053:                                            + captureResult, module);
1054:                            ServiceUtil
1055:                                    .returnError("Trouble processing the capture results");
1056:                        }
1057:
1058:                        // create any splits which are needed
1059:                        if (authAmount.doubleValue() > amountThisCapture) {
1060:                            // create a new payment preference and authorize it
1061:                            Debug.logInfo("Creating payment preference split",
1062:                                    module);
1063:                            double newAmount = authAmount.doubleValue()
1064:                                    - amountThisCapture;
1065:                            String newPrefId = delegator.getNextSeqId(
1066:                                    "OrderPaymentPreference").toString();
1067:                            GenericValue newPref = delegator.makeValue(
1068:                                    "OrderPaymentPreference", UtilMisc.toMap(
1069:                                            "orderPaymentPreferenceId",
1070:                                            newPrefId));
1071:                            newPref.set("orderId", paymentPref.get("orderId"));
1072:                            newPref.set("paymentMethodTypeId", paymentPref
1073:                                    .get("paymentMethodTypeId"));
1074:                            newPref.set("paymentMethodId", paymentPref
1075:                                    .get("paymentMethodId"));
1076:                            newPref.set("maxAmount", paymentPref
1077:                                    .get("maxAmount"));
1078:                            newPref.set("statusId", "PAYMENT_NOT_AUTH");
1079:                            Debug
1080:                                    .logInfo("New preference : " + newPref,
1081:                                            module);
1082:                            try {
1083:                                // create the new payment preference
1084:                                delegator.create(newPref);
1085:
1086:                                // authorize the new preference
1087:                                Map processorResult = authPayment(dispatcher,
1088:                                        userLogin, orh, newPref, newAmount,
1089:                                        false);
1090:                                if (processorResult != null) {
1091:                                    GenericValue pSetting = (GenericValue) processorResult
1092:                                            .get("paymentSettings");
1093:                                    Double this Amount = (Double) processorResult
1094:                                            .get("processAmount");
1095:
1096:                                    // process the auth results
1097:                                    boolean authResult = false;
1098:                                    try {
1099:                                        authResult = processResult(dctx,
1100:                                                processorResult, userLogin,
1101:                                                newPref, pSetting);
1102:                                        if (!authResult) {
1103:                                            Debug.logError(
1104:                                                    "Authorization failed : "
1105:                                                            + newPref + " : "
1106:                                                            + processorResult,
1107:                                                    module);
1108:                                        }
1109:                                    } catch (GeneralException e) {
1110:                                        Debug.logError(e,
1111:                                                "Trouble processing the auth result : "
1112:                                                        + newPref + " : "
1113:                                                        + processorResult,
1114:                                                module);
1115:                                    }
1116:                                } else {
1117:                                    Debug.logError(
1118:                                            "Payment not authorized : "
1119:                                                    + newPref + " : "
1120:                                                    + processorResult, module);
1121:                                }
1122:                            } catch (GenericEntityException e) {
1123:                                Debug.logError(e,
1124:                                        "ERROR: cannot create new payment preference : "
1125:                                                + newPref, module);
1126:                            }
1127:                        }
1128:                    } else {
1129:                        Debug.logError("Payment not captured", module);
1130:                        continue;
1131:                    }
1132:                }
1133:
1134:                if (amountToCapture > 0.00) {
1135:                    result.put(ModelService.RESPONSE_MESSAGE,
1136:                            ModelService.RESPOND_SUCCESS);
1137:                    result.put("processResult", "FAILED");
1138:                    return result;
1139:                } else {
1140:                    result.put(ModelService.RESPONSE_MESSAGE,
1141:                            ModelService.RESPOND_SUCCESS);
1142:                    result.put("processResult", "COMPLETE");
1143:                    return result;
1144:                }
1145:            }
1146:
1147:            private static Map capturePayment(LocalDispatcher dispatcher,
1148:                    GenericValue userLogin, OrderReadHelper orh,
1149:                    GenericValue paymentPref, double amount) {
1150:                // look up the payment configuration settings
1151:                String serviceName = null;
1152:                String paymentConfig = null;
1153:
1154:                // get the payment settings i.e. serviceName and config properties file name
1155:                GenericValue paymentSettings = getPaymentSettings(orh
1156:                        .getOrderHeader(), paymentPref, CAPTURE_SERVICE_TYPE,
1157:                        false);
1158:                if (paymentSettings != null) {
1159:                    paymentConfig = paymentSettings
1160:                            .getString("paymentPropertiesPath");
1161:                    serviceName = paymentSettings.getString("paymentService");
1162:                    if (serviceName == null) {
1163:                        Debug
1164:                                .logError(
1165:                                        "Service name is null for payment setting; cannot process",
1166:                                        module);
1167:                        return null;
1168:                    }
1169:                } else {
1170:                    Debug
1171:                            .logError(
1172:                                    "Invalid payment settings entity, no payment settings found",
1173:                                    module);
1174:                    return null;
1175:                }
1176:
1177:                if (paymentConfig == null || paymentConfig.length() == 0) {
1178:                    paymentConfig = "payment.properties";
1179:                }
1180:
1181:                // prepare the context for the capture service (must follow the ccCaptureInterface
1182:                Map captureContext = new HashMap();
1183:                captureContext.put("userLogin", userLogin);
1184:                captureContext.put("orderPaymentPreference", paymentPref);
1185:                captureContext.put("paymentConfig", paymentConfig);
1186:                captureContext.put("captureAmount", new Double(amount));
1187:                captureContext.put("currency", orh.getCurrency());
1188:
1189:                Debug.logInfo("Capture [" + serviceName + "] : "
1190:                        + captureContext, module);
1191:
1192:                // now invoke the capture service
1193:                Map captureResult = null;
1194:                try {
1195:                    captureResult = dispatcher.runSync(serviceName,
1196:                            captureContext);
1197:                } catch (GenericServiceException e) {
1198:                    Debug.logError(e,
1199:                            "Could not capture payment ... serviceName: "
1200:                                    + serviceName + " ... context: "
1201:                                    + captureContext, module);
1202:                    return null;
1203:                }
1204:
1205:                // pass the payTo partyId to the result processor; we just add it to the result context.
1206:                String payToPartyId = getPayToPartyId(orh.getOrderHeader());
1207:                captureResult.put("payToPartyId", payToPartyId);
1208:
1209:                // add paymentSettings to result; for use by later processors
1210:                captureResult.put("paymentSettings", paymentSettings);
1211:
1212:                return captureResult;
1213:            }
1214:
1215:            private static boolean processResult(DispatchContext dctx,
1216:                    Map result, GenericValue userLogin,
1217:                    GenericValue paymentPreference, GenericValue paymentSettings)
1218:                    throws GeneralException {
1219:                Boolean authResult = (Boolean) result.get("authResult");
1220:                Boolean captureResult = (Boolean) result.get("captureResult");
1221:                boolean resultPassed = false;
1222:                boolean fromAuth = false;
1223:
1224:                if (authResult != null) {
1225:                    processAuthResult(dctx, result, userLogin,
1226:                            paymentPreference, paymentSettings);
1227:                    resultPassed = authResult.booleanValue();
1228:                    fromAuth = true;
1229:                }
1230:                if (captureResult != null) {
1231:                    processCaptureResult(dctx, result, userLogin,
1232:                            paymentPreference, paymentSettings, fromAuth);
1233:                    if (!resultPassed)
1234:                        resultPassed = captureResult.booleanValue();
1235:                }
1236:                return resultPassed;
1237:            }
1238:
1239:            private static void processAuthResult(DispatchContext dctx,
1240:                    Map result, GenericValue userLogin,
1241:                    GenericValue paymentPreference, GenericValue paymentSettings)
1242:                    throws GeneralException {
1243:                Boolean authResult = (Boolean) result.get("authResult");
1244:                GenericDelegator delegator = paymentPreference.getDelegator();
1245:
1246:                // type of auth this was can be determined by the previous status
1247:                String authType = paymentPreference.getString("statusId")
1248:                        .equals("PAYMENT_NOT_AUTH") ? AUTH_SERVICE_TYPE
1249:                        : REAUTH_SERVICE_TYPE;
1250:
1251:                // create the PaymentGatewayResponse
1252:                String responseId = delegator.getNextSeqId(
1253:                        "PaymentGatewayResponse").toString();
1254:                GenericValue response = delegator.makeValue(
1255:                        "PaymentGatewayResponse", null);
1256:                response.set("paymentGatewayResponseId", responseId);
1257:                response.set("paymentServiceTypeEnumId", authType);
1258:                response.set("orderPaymentPreferenceId", paymentPreference
1259:                        .get("orderPaymentPreferenceId"));
1260:                response.set("paymentMethodTypeId", paymentPreference
1261:                        .get("paymentMethodTypeId"));
1262:                response.set("paymentMethodId", paymentPreference
1263:                        .get("paymentMethodId"));
1264:
1265:                // set the avs/fraud result
1266:                response.set("gatewayAvsResult", result.get("avsCode"));
1267:                response.set("gatewayScoreResult", result.get("scoreCode"));
1268:
1269:                // set the auth info
1270:                response.set("amount", result.get("processAmount"));
1271:                response.set("referenceNum", result.get("authRefNum"));
1272:                response.set("gatewayCode", result.get("authCode"));
1273:                response.set("gatewayFlag", result.get("authFlag"));
1274:                response.set("gatewayMessage", result.get("authMessage"));
1275:                response.set("transactionDate", UtilDateTime.nowTimestamp());
1276:                delegator.create(response);
1277:
1278:                if (response.getDouble("amount").doubleValue() != ((Double) result
1279:                        .get("processAmount")).doubleValue()) {
1280:                    Debug.logWarning(
1281:                            "The authorized amount does not match the max amount : Response - "
1282:                                    + response + " : result - " + result,
1283:                            module);
1284:                }
1285:
1286:                // set the status of the OrderPaymentPreference
1287:                if (result != null && authResult.booleanValue()) {
1288:                    paymentPreference.set("statusId", "PAYMENT_AUTHORIZED");
1289:                } else if (result != null && !authResult.booleanValue()) {
1290:                    paymentPreference.set("statusId", "PAYMENT_DECLINED");
1291:                } else {
1292:                    paymentPreference.set("statusId", "PAYMENT_ERROR");
1293:                }
1294:                paymentPreference.store();
1295:            }
1296:
1297:            private static void processCaptureResult(DispatchContext dctx,
1298:                    Map result, GenericValue userLogin,
1299:                    GenericValue paymentPreference, GenericValue paymentSettings)
1300:                    throws GeneralException {
1301:                processCaptureResult(dctx, result, userLogin,
1302:                        paymentPreference, paymentSettings, false);
1303:            }
1304:
1305:            private static void processCaptureResult(DispatchContext dctx,
1306:                    Map result, GenericValue userLogin,
1307:                    GenericValue paymentPreference,
1308:                    GenericValue paymentSettings, boolean fromAuth)
1309:                    throws GeneralException {
1310:                Boolean captureResult = (Boolean) result.get("captureResult");
1311:                String invoiceId = (String) result.get("invoiceId");
1312:                String payTo = (String) result.get("payToPartyId");
1313:                GenericDelegator delegator = dctx.getDelegator();
1314:                LocalDispatcher dispatcher = dctx.getDispatcher();
1315:                Double amount = null;
1316:                if (result.get("captureAmount") != null) {
1317:                    amount = (Double) result.get("captureAmount");
1318:                } else if (result.get("processAmount") != null) {
1319:                    amount = (Double) result.get("processAmount");
1320:                }
1321:
1322:                if (amount == null) {
1323:                    throw new GeneralException(
1324:                            "Unable to process null capture amount");
1325:                }
1326:
1327:                Debug.logInfo("Invoice ID: " + invoiceId, module);
1328:
1329:                if (payTo == null)
1330:                    payTo = "Company";
1331:
1332:                String serviceType = fromAuth ? "AUTH" : CAPTURE_SERVICE_TYPE;
1333:                if (serviceType.equals("AUTH")) {
1334:                    serviceType = paymentPreference.getString("statusId")
1335:                            .equals("PAYMENT_NOT_AUTH") ? AUTH_SERVICE_TYPE
1336:                            : REAUTH_SERVICE_TYPE;
1337:                }
1338:
1339:                if (result != null && captureResult.booleanValue()) {
1340:                    // create the PaymentGatewayResponse record
1341:                    String responseId = delegator.getNextSeqId(
1342:                            "PaymentGatewayResponse").toString();
1343:                    GenericValue response = delegator.makeValue(
1344:                            "PaymentGatewayResponse", null);
1345:                    response.set("paymentGatewayResponseId", responseId);
1346:                    response.set("paymentServiceTypeEnumId", serviceType);
1347:                    response.set("orderPaymentPreferenceId", paymentPreference
1348:                            .get("orderPaymentPreferenceId"));
1349:                    response.set("paymentMethodTypeId", paymentPreference
1350:                            .get("paymentMethodTypeId"));
1351:                    response.set("paymentMethodId", paymentPreference
1352:                            .get("paymentMethodId"));
1353:                    if (result.get("authRefNum") != null) {
1354:                        response.set("subReference", result.get("authRefNum"));
1355:                    }
1356:
1357:                    // set the capture info
1358:                    response.set("amount", amount);
1359:                    response.set("referenceNum", result.get("captureRefNum"));
1360:                    response.set("gatewayCode", result.get("captureCode"));
1361:                    response.set("gatewayFlag", result.get("captureFlag"));
1362:                    response
1363:                            .set("gatewayMessage", result.get("captureMessage"));
1364:                    response
1365:                            .set("transactionDate", UtilDateTime.nowTimestamp());
1366:                    delegator.create(response);
1367:
1368:                    String orderId = paymentPreference.getString("orderId");
1369:                    GenericValue orderRole = EntityUtil
1370:                            .getFirst(delegator.findByAnd("OrderRole", UtilMisc
1371:                                    .toMap("orderId", orderId, "roleTypeId",
1372:                                            "BILL_TO_CUSTOMER")));
1373:
1374:                    Map paymentCtx = UtilMisc.toMap("paymentTypeId", "RECEIPT");
1375:                    paymentCtx.put("paymentMethodTypeId", paymentPreference
1376:                            .get("paymentMethodTypeId"));
1377:                    paymentCtx.put("paymentMethodId", paymentPreference
1378:                            .get("paymentMethodId"));
1379:                    paymentCtx.put("paymentGatewayResponseId", responseId);
1380:                    paymentCtx.put("partyIdTo", payTo);
1381:                    paymentCtx.put("partyIdFrom", orderRole.get("partyId"));
1382:                    paymentCtx.put("statusId", "PMNT_RECEIVED");
1383:                    paymentCtx.put("paymentPreferenceId", paymentPreference
1384:                            .get("orderPaymentPreferenceId"));
1385:                    paymentCtx.put("amount", amount);
1386:                    paymentCtx.put("userLogin", userLogin);
1387:                    paymentCtx
1388:                            .put("paymentRefNum", result.get("captureRefNum"));
1389:
1390:                    Map payRes = dispatcher
1391:                            .runSync("createPayment", paymentCtx);
1392:                    String paymentId = (String) payRes.get("paymentId");
1393:
1394:                    paymentPreference.set("statusId", "PAYMENT_SETTLED");
1395:                    paymentPreference.store();
1396:
1397:                    // create the PaymentApplication if invoiceId is available
1398:                    if (invoiceId != null) {
1399:                        Debug.logInfo("Processing Invoice #" + invoiceId,
1400:                                module);
1401:                        Map paCtx = UtilMisc.toMap("paymentId", paymentId,
1402:                                "invoiceId", invoiceId);
1403:                        paCtx.put("amountApplied", result.get("captureAmount"));
1404:                        paCtx.put("userLogin", userLogin);
1405:                        Map paRes = dispatcher.runSync(
1406:                                "createPaymentApplication", paCtx);
1407:                    }
1408:                } else if (result != null && !captureResult.booleanValue()) {
1409:                    // problem with the capture lets get some needed info
1410:                    OrderReadHelper orh = null;
1411:                    try {
1412:                        GenericValue orderHeader = paymentPreference
1413:                                .getRelatedOne("OrderHeader");
1414:                        if (orderHeader != null)
1415:                            orh = new OrderReadHelper(orderHeader);
1416:                    } catch (GenericEntityException e) {
1417:                        Debug
1418:                                .logError(
1419:                                        e,
1420:                                        "Problems getting OrderHeader; cannot re-auth the payment",
1421:                                        module);
1422:                    }
1423:
1424:                    if (orh != null) {
1425:                        // first lets re-auth the card
1426:                        Map authPayRes = authPayment(dispatcher, userLogin,
1427:                                orh, paymentPreference, amount.doubleValue(),
1428:                                true);
1429:                        if (authPayRes != null) {
1430:                            Boolean authResp = (Boolean) result
1431:                                    .get("authResult");
1432:                            Boolean capResp = (Boolean) result
1433:                                    .get("captureResult");
1434:                            if (authResp != null) {
1435:                                processAuthResult(dctx, authPayRes, userLogin,
1436:                                        paymentPreference, paymentSettings);
1437:                                if (authResp.booleanValue()) {
1438:                                    // first make sure we didn't already capture - probably not
1439:                                    if (capResp != null
1440:                                            && capResp.booleanValue()) {
1441:                                        processCaptureResult(dctx, result,
1442:                                                userLogin, paymentPreference,
1443:                                                paymentSettings);
1444:                                    } else {
1445:                                        // lets try to capture the funds now
1446:                                        Map capPayRes = capturePayment(
1447:                                                dispatcher, userLogin, orh,
1448:                                                paymentPreference, amount
1449:                                                        .doubleValue());
1450:                                        if (capPayRes != null) {
1451:                                            Boolean capPayResp = (Boolean) result
1452:                                                    .get("captureResult");
1453:                                            if (capPayResp != null
1454:                                                    && capPayResp
1455:                                                            .booleanValue()) {
1456:                                                // it was successful
1457:                                                processCaptureResult(dctx,
1458:                                                        result, userLogin,
1459:                                                        paymentPreference,
1460:                                                        paymentSettings);
1461:                                            } else {
1462:                                                // not successful; log it
1463:                                                Debug
1464:                                                        .logError(
1465:                                                                "Capture of authorized payment failed: "
1466:                                                                        + paymentPreference,
1467:                                                                module);
1468:                                            }
1469:                                        } else {
1470:                                            Debug
1471:                                                    .logError(
1472:                                                            "Problems trying to capture payment (null result): "
1473:                                                                    + paymentPreference,
1474:                                                            module);
1475:                                        }
1476:                                    }
1477:                                } else {
1478:                                    Debug
1479:                                            .logError(
1480:                                                    "Payment authorization failed:  "
1481:                                                            + paymentPreference,
1482:                                                    module);
1483:                                }
1484:                            } else {
1485:                                Debug.logError(
1486:                                        "Payment authorization failed (null result):  "
1487:                                                + paymentPreference, module);
1488:                            }
1489:                        } else {
1490:                            Debug.logError(
1491:                                    "Problems trying to re-authorize the payment (null result): "
1492:                                            + paymentPreference, module);
1493:                        }
1494:                    } else {
1495:                        Debug.logError("Null OrderReadHelper cannot process",
1496:                                module);
1497:                    }
1498:                } else {
1499:                    Debug.logError("Result pass is null, no capture available",
1500:                            module);
1501:                }
1502:            }
1503:
1504:            public static Map refundPayment(DispatchContext dctx, Map context) {
1505:                GenericDelegator delegator = dctx.getDelegator();
1506:                LocalDispatcher dispatcher = dctx.getDispatcher();
1507:                GenericValue userLogin = (GenericValue) context
1508:                        .get("userLogin");
1509:
1510:                GenericValue paymentPref = (GenericValue) context
1511:                        .get("orderPaymentPreference");
1512:                Double refundAmount = (Double) context.get("refundAmount");
1513:
1514:                GenericValue orderHeader = null;
1515:                try {
1516:                    orderHeader = paymentPref.getRelatedOne("OrderHeader");
1517:                } catch (GenericEntityException e) {
1518:                    Debug
1519:                            .logError(
1520:                                    e,
1521:                                    "Cannot get OrderHeader from OrderPaymentPreference",
1522:                                    module);
1523:                    return ServiceUtil
1524:                            .returnError("Problems getting OrderHeader from OrderPaymentPreference: "
1525:                                    + e.getMessage());
1526:                }
1527:
1528:                OrderReadHelper orh = new OrderReadHelper(orderHeader);
1529:
1530:                GenericValue paymentSettings = null;
1531:                if (orderHeader != null) {
1532:                    paymentSettings = getPaymentSettings(orderHeader,
1533:                            paymentPref, REFUND_SERVICE_TYPE, false);
1534:                }
1535:
1536:                if (paymentSettings != null) {
1537:                    String paymentConfig = paymentSettings
1538:                            .getString("paymentPropertiesPath");
1539:                    String serviceName = paymentSettings
1540:                            .getString("paymentService");
1541:                    if (serviceName != null) {
1542:                        Map serviceContext = new HashMap();
1543:                        serviceContext.put("orderPaymentPreference",
1544:                                paymentPref);
1545:                        serviceContext.put("paymentConfig", paymentConfig);
1546:                        serviceContext.put("currency", orh.getCurrency());
1547:
1548:                        // get the creditCard/address/email
1549:                        String payToPartyId = null;
1550:                        try {
1551:                            payToPartyId = getBillingInformation(orh,
1552:                                    paymentPref, new HashMap());
1553:                        } catch (GenericEntityException e) {
1554:                            Debug.logError(e,
1555:                                    "Problems getting billing information",
1556:                                    module);
1557:                            return ServiceUtil
1558:                                    .returnError("Problems getting billing information");
1559:                        }
1560:
1561:                        // format the price
1562:                        String currencyFormat = UtilProperties
1563:                                .getPropertyValue("general.properties",
1564:                                        "currency.decimal.format", "##0.00");
1565:                        DecimalFormat formatter = new DecimalFormat(
1566:                                currencyFormat);
1567:                        String amountString = formatter.format(refundAmount);
1568:                        Double processAmount = null;
1569:                        try {
1570:                            processAmount = new Double(formatter.parse(
1571:                                    amountString).doubleValue());
1572:                        } catch (ParseException e) {
1573:                            Debug
1574:                                    .logError(
1575:                                            e,
1576:                                            "Problem parsing amount using DecimalFormat",
1577:                                            module);
1578:                            return ServiceUtil
1579:                                    .returnError("Refund processor problems; see logs");
1580:                        }
1581:                        serviceContext.put("refundAmount", processAmount);
1582:                        serviceContext.put("userLogin", userLogin);
1583:
1584:                        // call the service
1585:                        Map refundResponse = null;
1586:                        try {
1587:                            refundResponse = dispatcher.runSync(serviceName,
1588:                                    serviceContext);
1589:                        } catch (GenericServiceException e) {
1590:                            Debug
1591:                                    .logError(
1592:                                            e,
1593:                                            "Problem refunding payment through processor",
1594:                                            module);
1595:                            return ServiceUtil
1596:                                    .returnError("Refund processor problems; see logs");
1597:                        }
1598:
1599:                        //Debug.log("Called Electronic Refund Service : " + refundResponse, module);
1600:
1601:                        // get the pay-from party
1602:                        if (paymentConfig == null
1603:                                || paymentConfig.length() == 0) {
1604:                            paymentConfig = "payment.properties";
1605:                        }
1606:                        String payFromPartyId = getPayToPartyId(orderHeader);
1607:
1608:                        // create the PaymentGatewayResponse record
1609:                        String responseId = delegator.getNextSeqId(
1610:                                "PaymentGatewayResponse").toString();
1611:                        GenericValue response = delegator.makeValue(
1612:                                "PaymentGatewayResponse", null);
1613:                        response.set("paymentGatewayResponseId", responseId);
1614:                        response.set("paymentServiceTypeEnumId",
1615:                                REFUND_SERVICE_TYPE);
1616:                        response.set("orderPaymentPreferenceId", paymentPref
1617:                                .get("orderPaymentPreferenceId"));
1618:                        response.set("paymentMethodTypeId", paymentPref
1619:                                .get("paymentMethodTypeId"));
1620:                        response.set("paymentMethodId", paymentPref
1621:                                .get("paymentMethodId"));
1622:
1623:                        // set the capture info
1624:                        response.set("amount", refundResponse
1625:                                .get("refundAmount"));
1626:                        response.set("referenceNum", refundResponse
1627:                                .get("refundRefNum"));
1628:                        response.set("gatewayCode", refundResponse
1629:                                .get("refundCode"));
1630:                        response.set("gatewayFlag", refundResponse
1631:                                .get("refundFlag"));
1632:                        response.set("gatewayMessage", refundResponse
1633:                                .get("refundMessage"));
1634:                        response.set("transactionDate", UtilDateTime
1635:                                .nowTimestamp());
1636:                        try {
1637:                            delegator.create(response);
1638:                        } catch (GenericEntityException e) {
1639:                            Debug.logError(e, module);
1640:                            return ServiceUtil
1641:                                    .returnError("Unable to create PaymentGatewayResponse record");
1642:                        }
1643:
1644:                        // handle the (reverse) payment
1645:                        Boolean refundResult = (Boolean) refundResponse
1646:                                .get("refundResult");
1647:                        if (refundResult != null && refundResult.booleanValue()) {
1648:                            // create a payment record
1649:                            Map paymentCtx = UtilMisc.toMap("paymentTypeId",
1650:                                    "DISBURSEMENT");
1651:                            paymentCtx.put("paymentMethodTypeId", paymentPref
1652:                                    .get("paymentMethodTypeId"));
1653:                            paymentCtx.put("paymentMethodId", paymentPref
1654:                                    .get("paymentMethodId"));
1655:                            paymentCtx.put("paymentGatewayResponseId",
1656:                                    responseId);
1657:                            paymentCtx.put("partyIdTo", payToPartyId);
1658:                            paymentCtx.put("partyIdFrom", payFromPartyId);
1659:                            paymentCtx.put("statusId", "PMNT_SENT");
1660:                            paymentCtx.put("paymentPreferenceId", paymentPref
1661:                                    .get("orderPaymentPreferenceId"));
1662:                            paymentCtx.put("amount", refundResponse
1663:                                    .get("refundAmount"));
1664:                            paymentCtx.put("userLogin", userLogin);
1665:                            paymentCtx.put("paymentRefNum", refundResponse
1666:                                    .get("refundRefNum"));
1667:                            paymentCtx.put("comments", "Refund");
1668:
1669:                            String paymentId = null;
1670:                            try {
1671:                                Map payRes = dispatcher.runSync(
1672:                                        "createPayment", paymentCtx);
1673:                                if (ModelService.RESPOND_ERROR.equals(payRes
1674:                                        .get(ModelService.RESPONSE_MESSAGE))) {
1675:                                    return ServiceUtil
1676:                                            .returnError((String) payRes
1677:                                                    .get(ModelService.ERROR_MESSAGE));
1678:                                } else {
1679:                                    paymentId = (String) payRes
1680:                                            .get("paymentId");
1681:                                }
1682:                            } catch (GenericServiceException e) {
1683:                                Debug.logError(e, "Problem creating Payment",
1684:                                        module);
1685:                                return ServiceUtil
1686:                                        .returnError("Problem creating Payment");
1687:                            }
1688:                            //Debug.log("Payment created : " + paymentId, module);
1689:
1690:                            if (paymentId == null) {
1691:                                return ServiceUtil
1692:                                        .returnError("Create payment failed");
1693:                            }
1694:
1695:                            Map result = ServiceUtil.returnSuccess();
1696:                            result.put("paymentId", "10000");
1697:                            return result;
1698:                        } else {
1699:                            return ServiceUtil.returnError("The refund failed");
1700:                        }
1701:                    } else {
1702:                        return ServiceUtil
1703:                                .returnError("No refund service defined");
1704:                    }
1705:                } else {
1706:                    return ServiceUtil.returnError("No payment settings found");
1707:                }
1708:            }
1709:
1710:            public static Map retryFailedAuths(DispatchContext dctx, Map context) {
1711:                return ServiceUtil.returnError("Service not yet implemented");
1712:            }
1713:
1714:            public static GenericValue getAuthTransaction(
1715:                    GenericValue orderPaymentPreference) {
1716:                GenericValue authTrans = null;
1717:                try {
1718:                    List order = UtilMisc.toList("transactionDate");
1719:                    List transactions = orderPaymentPreference.getRelated(
1720:                            "PaymentGatewayResponse", null, order);
1721:
1722:                    List exprs = UtilMisc.toList(new EntityExpr(
1723:                            "paymentServiceTypeEnumId", EntityOperator.EQUALS,
1724:                            "PRDS_PAY_AUTH"), new EntityExpr(
1725:                            "paymentServiceTypeEnumId", EntityOperator.EQUALS,
1726:                            "PRDS_PAY_REAUTH"));
1727:
1728:                    List authTransactions = EntityUtil.filterByOr(transactions,
1729:                            exprs);
1730:                    authTrans = EntityUtil.getFirst(authTransactions);
1731:                } catch (GenericEntityException e) {
1732:                    Debug
1733:                            .logError(
1734:                                    e,
1735:                                    "ERROR: Problem getting authorization information from PaymentGatewayResponse",
1736:                                    module);
1737:                }
1738:                return authTrans;
1739:            }
1740:
1741:            // manual processing service
1742:            public static Map processManualCcTx(DispatchContext dctx,
1743:                    Map context) {
1744:                GenericValue userLogin = (GenericValue) context
1745:                        .get("userLogin");
1746:                LocalDispatcher dispatcher = dctx.getDispatcher();
1747:                GenericDelegator delegator = dctx.getDelegator();
1748:                Security security = dctx.getSecurity();
1749:
1750:                // security check
1751:                if (!security.hasEntityPermission("MANUAL", "_PAYMENT",
1752:                        userLogin)) {
1753:                    Debug.logWarning("**** Security ["
1754:                            + (new Date()).toString() + "]: "
1755:                            + userLogin.get("userLoginId")
1756:                            + " attempt to run manual payment transaction!",
1757:                            module);
1758:                    return ServiceUtil
1759:                            .returnError("You do not have permission for this transaction.");
1760:                }
1761:
1762:                String paymentMethodTypeId = (String) context
1763:                        .get("paymentMethodTypeId");
1764:                String productStoreId = (String) context.get("productStoreId");
1765:                String transactionType = (String) context
1766:                        .get("transactionType");
1767:                String referenceCode = (String) context.get("referenceCode");
1768:                if (referenceCode == null) {
1769:                    referenceCode = new Long(System.currentTimeMillis())
1770:                            .toString();
1771:                }
1772:
1773:                // check valid implemented types
1774:                if (!transactionType.equals("PRDS_PAY_CREDIT")) {
1775:                    return ServiceUtil
1776:                            .returnError("This transaction type is not yet supported.");
1777:                }
1778:
1779:                // transaction request context
1780:                Map requestContext = new HashMap();
1781:                String paymentService = null;
1782:                String paymentConfig = null;
1783:
1784:                // get the transaction settings
1785:                GenericValue paymentSettings = ProductStoreWorker
1786:                        .getProductStorePaymentSetting(delegator,
1787:                                productStoreId, paymentMethodTypeId,
1788:                                transactionType, false);
1789:                if (paymentSettings == null) {
1790:                    return ServiceUtil
1791:                            .returnError("No valid payment settings found for : "
1792:                                    + productStoreId + "/" + transactionType);
1793:                } else {
1794:                    paymentConfig = paymentSettings
1795:                            .getString("paymentPropertiesPath");
1796:                    paymentService = paymentSettings
1797:                            .getString("paymentService");
1798:                    requestContext.put("paymentConfig", paymentConfig);
1799:                }
1800:
1801:                // check the service name
1802:                if (paymentService == null || paymentConfig == null) {
1803:                    return ServiceUtil
1804:                            .returnError("Invalid product store payment settings");
1805:                }
1806:
1807:                if (paymentMethodTypeId.equals("CREDIT_CARD")) {
1808:                    GenericValue creditCard = delegator.makeValue("CreditCard",
1809:                            null);
1810:                    creditCard.setAllFields(context, true, null, null);
1811:                    if (creditCard.get("nameOnCard") == null
1812:                            || creditCard.get("cardType") == null
1813:                            || creditCard.get("cardNumber") == null) {
1814:                        return ServiceUtil
1815:                                .returnError("Credit card is missing required fields.");
1816:                    }
1817:                    String expMonth = (String) context.get("expMonth");
1818:                    String expYear = (String) context.get("expYear");
1819:                    String expDate = expMonth + "/" + expYear;
1820:                    creditCard.set("expireDate", expDate);
1821:                    requestContext.put("creditCard", creditCard);
1822:
1823:                    GenericValue billingAddress = delegator.makeValue(
1824:                            "PostalAddress", null);
1825:                    billingAddress.setAllFields(context, true, null, null);
1826:                    if (billingAddress.get("address1") == null
1827:                            || billingAddress.get("city") == null
1828:                            || billingAddress.get("postalCode") == null) {
1829:                        return ServiceUtil
1830:                                .returnError("Credit card billing address is missing required fields.");
1831:                    }
1832:                    requestContext.put("billingAddress", billingAddress);
1833:
1834:                    GenericValue contactPerson = delegator.makeValue("Person",
1835:                            null);
1836:                    contactPerson.setAllFields(context, true, null, null);
1837:                    if (contactPerson.get("firstName") == null
1838:                            || contactPerson.get("lastName") == null) {
1839:                        return ServiceUtil
1840:                                .returnError("Contact person is missing required fields.");
1841:                    }
1842:                    requestContext.put("contactPerson", contactPerson);
1843:
1844:                    GenericValue contactEmail = delegator.makeValue(
1845:                            "ContactMech", null);
1846:                    contactEmail.set("infoString", context.get("infoString"));
1847:                    if (contactEmail.get("infoString") == null) {
1848:                        return ServiceUtil
1849:                                .returnError("Email address field cannot be empty.");
1850:                    }
1851:                    requestContext.put("contactEmail", contactEmail);
1852:                    requestContext.put("referenceCode", referenceCode);
1853:                    requestContext.put("currency", "USD");
1854:                    requestContext.put("creditAmount", context.get("amount")); // TODO fix me to work w/ other services
1855:                } else {
1856:                    return ServiceUtil
1857:                            .returnError("Payment method type : "
1858:                                    + paymentMethodTypeId
1859:                                    + " is not yet implemented for manual transactions");
1860:                }
1861:
1862:                // process the transaction
1863:                Map response = null;
1864:                try {
1865:                    response = dispatcher.runSync(paymentService,
1866:                            requestContext);
1867:                } catch (GenericServiceException e) {
1868:                    Debug.logError(e, module);
1869:                    return ServiceUtil.returnError("Error calling service : "
1870:                            + paymentService + " / " + requestContext);
1871:                }
1872:
1873:                // check for errors
1874:                if (ServiceUtil.isError(response)) {
1875:                    return ServiceUtil
1876:                            .returnError(ServiceUtil.makeErrorMessage(response,
1877:                                    null, null, null, null));
1878:                }
1879:
1880:                // get the reference number // TODO add support for other tx types
1881:                String refNum = (String) response.get("creditRefNum");
1882:                String code = (String) response.get("creditCode");
1883:                String msg = (String) response.get("creditMessage");
1884:                Map returnResults = ServiceUtil
1885:                        .returnSuccess("Transaction result [" + msg + "/"
1886:                                + code + "] Ref#: " + refNum);
1887:                returnResults.put("referenceNum", refNum);
1888:                return returnResults;
1889:            }
1890:
1891:            // ****************************************************
1892:            // Test Services
1893:            // ****************************************************
1894:
1895:            /**
1896:             * Simple test processor; declines all orders < 100.00; approves all orders > 100.00
1897:             */
1898:            public static Map testProcessor(DispatchContext dctx, Map context) {
1899:                Map result = new HashMap();
1900:                Double processAmount = (Double) context.get("processAmount");
1901:
1902:                if (processAmount != null
1903:                        && processAmount.doubleValue() >= 100.00)
1904:                    result.put("authResult", new Boolean(true));
1905:                if (processAmount != null
1906:                        && processAmount.doubleValue() < 100.00)
1907:                    result.put("authResult", new Boolean(false));
1908:                if (processAmount == null)
1909:                    result.put("authResult", null);
1910:
1911:                long nowTime = new Date().getTime();
1912:
1913:                result.put("processAmount", context.get("processAmount"));
1914:                result.put("authRefNum", new Long(nowTime).toString());
1915:                result.put("authFlag", "X");
1916:                result
1917:                        .put("authMessage",
1918:                                "This is a test processor; no payments were captured or authorized.");
1919:                return result;
1920:            }
1921:
1922:            /**
1923:             * Always approve processor.
1924:             */
1925:            public static Map alwaysApproveProcessor(DispatchContext dctx,
1926:                    Map context) {
1927:                Map result = new HashMap();
1928:                Double processAmount = (Double) context.get("processAmount");
1929:                long nowTime = new Date().getTime();
1930:                Debug.logInfo("Test Processor Approving Credit Card", module);
1931:
1932:                result.put("authResult", new Boolean(true));
1933:                result.put("processAmount", context.get("processAmount"));
1934:                result.put("authRefNum", new Long(nowTime).toString());
1935:                result.put("authCode", "100");
1936:                result.put("authFlag", "A");
1937:                result
1938:                        .put("authMessage",
1939:                                "This is a test processor; no payments were captured or authorized.");
1940:                return result;
1941:            }
1942:
1943:            public static Map alwaysApproveWithCapture(DispatchContext dctx,
1944:                    Map context) {
1945:                Map result = new HashMap();
1946:                long nowTime = new Date().getTime();
1947:                String refNum = new Long(nowTime).toString();
1948:                Debug.logInfo(
1949:                        "Test Processor Approving Credit Card with Capture",
1950:                        module);
1951:
1952:                result.put("authResult", new Boolean(true));
1953:                result.put("captureResult", new Boolean(true));
1954:                result.put("processAmount", context.get("processAmount"));
1955:                result.put("authRefNum", refNum);
1956:                result.put("captureRefNum", refNum);
1957:                result.put("authCode", "100");
1958:                result.put("captureCode", "200");
1959:                result.put("authFlag", "A");
1960:                result
1961:                        .put("authMessage",
1962:                                "This is a test processor; no payments were captured or authorized.");
1963:                return result;
1964:            }
1965:
1966:            /**
1967:             * Always decline processor.
1968:             */
1969:            public static Map alwaysDeclineProcessor(DispatchContext dctx,
1970:                    Map context) {
1971:                Map result = new HashMap();
1972:                Double processAmount = (Double) context.get("processAmount");
1973:                long nowTime = new Date().getTime();
1974:                Debug.logInfo("Test Processor Declining Credit Card", module);
1975:
1976:                result.put("authResult", new Boolean(false));
1977:                result.put("processAmount", context.get("processAmount"));
1978:                result.put("authRefNum", new Long(nowTime).toString());
1979:                result.put("authFlag", "D");
1980:                result
1981:                        .put("authMessage",
1982:                                "This is a test processor; no payments were captured or authorized");
1983:                return result;
1984:            }
1985:
1986:            /**
1987:             * Always fail (error) processor
1988:             */
1989:            public static Map alwaysFailProcessor(DispatchContext dctx,
1990:                    Map context) {
1991:                return ServiceUtil
1992:                        .returnError("Unable to communicate with bla");
1993:            }
1994:
1995:            public static Map testRelease(DispatchContext dctx, Map context) {
1996:                Map result = new HashMap();
1997:                long nowTime = new Date().getTime();
1998:
1999:                result.put("releaseResult", new Boolean(true));
2000:                result.put("releaseAmount", context.get("releaseAmount"));
2001:                result.put("releaseRefNum", new Long(nowTime).toString());
2002:                result.put("releaseFlag", "U");
2003:                result.put("releaseMessage",
2004:                        "This is a test release; no authorizations exist");
2005:                return result;
2006:            }
2007:
2008:            /**
2009:             * Test capture service (returns true)
2010:             */
2011:            public static Map testCapture(DispatchContext dctx, Map context) {
2012:                Map result = new HashMap();
2013:                long nowTime = new Date().getTime();
2014:
2015:                result.put("captureResult", new Boolean(true));
2016:                result.put("captureAmount", context.get("captureAmount"));
2017:                result.put("captureRefNum", new Long(nowTime).toString());
2018:                result.put("captureFlag", "C");
2019:                result.put("captureMessage",
2020:                        "This is a test capture; no money was transferred");
2021:                return result;
2022:            }
2023:
2024:            /**
2025:             * Test refund service (returns true)
2026:             */
2027:            public static Map testRefund(DispatchContext dctx, Map context) {
2028:                Map result = new HashMap();
2029:                long nowTime = new Date().getTime();
2030:
2031:                result.put("refundResult", new Boolean(true));
2032:                result.put("refundAmount", context.get("refundAmount"));
2033:                result.put("refundRefNum", new Long(nowTime).toString());
2034:                result.put("refundFlag", "R");
2035:                result.put("refundMessage",
2036:                        "This is a test refund; no money was transferred");
2037:                return result;
2038:            }
2039:
2040:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.