1 24 25 package org.ofbiz.accounting.thirdparty.clearcommerce; 26 27 import java.util.Map ; 28 import java.util.List ; 29 import java.util.Iterator ; 30 import java.util.ArrayList ; 31 import java.text.DecimalFormat ; 32 import java.io.OutputStream ; 33 import java.io.ByteArrayOutputStream ; 34 import java.io.IOException ; 35 36 import javax.xml.parsers.ParserConfigurationException ; 37 38 import org.ofbiz.base.util.*; 39 import org.ofbiz.entity.GenericValue; 40 import org.ofbiz.entity.GenericEntityException; 41 import org.ofbiz.service.DispatchContext; 42 import org.ofbiz.service.ServiceUtil; 43 import org.ofbiz.accounting.payment.PaymentGatewayServices; 44 import org.w3c.dom.Document ; 45 import org.w3c.dom.Element ; 46 import org.xml.sax.SAXException ; 47 import org.apache.xml.serialize.XMLSerializer; 48 import org.apache.xml.serialize.OutputFormat; 49 50 51 57 public class CCPaymentServices { 58 59 public final static String module = CCPaymentServices.class.getName(); 60 61 62 public static Map ccAuth(DispatchContext dctx, Map context) { 63 64 Document authRequestDoc = buildPrimaryTxRequest(context, "PreAuth", (Double ) context.get("processAmount"), 65 (String ) context.get("orderId")); 66 67 Document authResponseDoc = null; 68 try { 69 authResponseDoc = sendRequest(authRequestDoc, (String ) context.get("paymentConfig")); 70 } catch (ClearCommerceException cce) { 71 return ServiceUtil.returnError(cce.getMessage()); 72 } 73 74 if (getMessageListMaxSev(authResponseDoc) > 4) { 75 Map result = ServiceUtil.returnSuccess(); 76 result.put("authResult", new Boolean (false)); 77 result.put("processAmount", new Double (0.00)); 78 result.put("authRefNum", getReferenceNum(authResponseDoc)); 79 List messages = getMessageList(authResponseDoc); 80 if (UtilValidate.isNotEmpty(messages)) { 81 result.put("internalRespMsgs", messages); 82 } 83 return result; 84 } 85 86 return processAuthResponse(authResponseDoc); 87 } 88 89 public static Map ccCredit(DispatchContext dctx, Map context) { 90 91 Document creditRequestDoc = buildPrimaryTxRequest(context, "Credit", (Double ) context.get("creditAmount"), 92 (String ) context.get("referenceCode")); 93 94 Document creditResponseDoc = null; 95 try { 96 creditResponseDoc = sendRequest(creditRequestDoc, (String ) context.get("paymentConfig")); 97 } catch (ClearCommerceException cce) { 98 return ServiceUtil.returnError(cce.getMessage()); 99 } 100 101 if (getMessageListMaxSev(creditResponseDoc) > 4) { 102 Map result = ServiceUtil.returnSuccess(); 103 result.put("creditResult", new Boolean (false)); 104 result.put("creditAmount", new Double (0.00)); 105 result.put("creditRefNum", getReferenceNum(creditResponseDoc)); 106 List messages = getMessageList(creditResponseDoc); 107 if (UtilValidate.isNotEmpty(messages)) { 108 result.put("internalRespMsgs", messages); 109 } 110 return result; 111 } 112 113 return processCreditResponse(creditResponseDoc); 114 } 115 116 public static Map ccCapture(DispatchContext dctx, Map context) { 117 118 GenericValue orderPaymentPreference = (GenericValue) context.get("orderPaymentPreference"); 119 GenericValue authTransaction = PaymentGatewayServices.getAuthTransaction(orderPaymentPreference); 120 if (authTransaction == null) { 121 return ServiceUtil.returnError("No authorization transaction found; cannot capture"); 122 } 123 124 Document captureRequestDoc = buildSecondaryTxRequest(context, authTransaction.getString("referenceNum"), 125 "PostAuth", (Double ) context.get("captureAmount")); 126 127 Document captureResponseDoc = null; 128 try { 129 captureResponseDoc = sendRequest(captureRequestDoc, (String ) context.get("paymentConfig")); 130 } catch (ClearCommerceException cce) { 131 return ServiceUtil.returnError(cce.getMessage()); 132 } 133 134 if (getMessageListMaxSev(captureResponseDoc) > 4) { 135 Map result = ServiceUtil.returnSuccess(); 136 result.put("captureResult", new Boolean (false)); 137 result.put("captureAmount", new Double (0.00)); 138 result.put("captureRefNum", getReferenceNum(captureResponseDoc)); 139 List messages = getMessageList(captureResponseDoc); 140 if (UtilValidate.isNotEmpty(messages)) { 141 result.put("internalRespMsgs", messages); 142 } 143 return result; 144 } 145 146 return processCaptureResponse(captureResponseDoc); 147 } 148 149 public static Map ccRelease(DispatchContext dctx, Map context) { 150 151 GenericValue orderPaymentPreference = (GenericValue) context.get("orderPaymentPreference"); 152 GenericValue authTransaction = PaymentGatewayServices.getAuthTransaction(orderPaymentPreference); 153 if (authTransaction == null) { 154 return ServiceUtil.returnError("No authorization transaction found; cannot release"); 155 } 156 157 Document releaseRequestDoc = buildSecondaryTxRequest(context, authTransaction.getString("referenceNum"), "Void", null); 158 159 Document releaseResponseDoc = null; 160 try { 161 releaseResponseDoc = sendRequest(releaseRequestDoc, (String ) context.get("paymentConfig")); 162 } catch (ClearCommerceException cce) { 163 return ServiceUtil.returnError(cce.getMessage()); 164 } 165 166 if (getMessageListMaxSev(releaseResponseDoc) > 4) { 167 Map result = ServiceUtil.returnSuccess(); 168 result.put("releaseResult", new Boolean (false)); 169 result.put("releaseAmount", new Double (0.00)); 170 result.put("releaseRefNum", getReferenceNum(releaseResponseDoc)); 171 List messages = getMessageList(releaseResponseDoc); 172 if (UtilValidate.isNotEmpty(messages)) { 173 result.put("internalRespMsgs", messages); 174 } 175 return result; 176 } 177 178 return processReleaseResponse(releaseResponseDoc); 179 } 180 181 public static Map ccReleaseNoop(DispatchContext dctx, Map context) { 182 183 GenericValue orderPaymentPreference = (GenericValue) context.get("orderPaymentPreference"); 184 GenericValue authTransaction = PaymentGatewayServices.getAuthTransaction(orderPaymentPreference); 185 if (authTransaction == null) { 186 return ServiceUtil.returnError("No authorization transaction found; cannot release"); 187 } 188 189 Map result = ServiceUtil.returnSuccess(); 190 result.put("releaseResult", Boolean.valueOf(true)); 191 result.put("releaseCode", authTransaction.getString("gatewayCode")); 192 result.put("releaseAmount", authTransaction.getDouble("amount")); 193 result.put("releaseRefNum", authTransaction.getString("referenceNum")); 194 result.put("releaseFlag", authTransaction.getString("gatewayFlag")); 195 result.put("releaseMessage", "Approved."); 196 197 return result; 198 } 199 200 public static Map ccRefund(DispatchContext dctx, Map context) { 201 202 GenericValue orderPaymentPreference = (GenericValue) context.get("orderPaymentPreference"); 203 GenericValue authTransaction = PaymentGatewayServices.getAuthTransaction(orderPaymentPreference); 204 if (authTransaction == null) { 205 return ServiceUtil.returnError("No authorization transaction found; cannot refund"); 206 } 207 208 Document refundRequestDoc = buildSecondaryTxRequest(context, authTransaction.getString("referenceNum"), 211 "Credit", (Double ) context.get("refundAmount")); 212 213 Document refundResponseDoc = null; 214 try { 215 refundResponseDoc = sendRequest(refundRequestDoc, (String ) context.get("paymentConfig")); 216 } catch (ClearCommerceException cce) { 217 return ServiceUtil.returnError(cce.getMessage()); 218 } 219 220 if (getMessageListMaxSev(refundResponseDoc) > 4) { 221 Map result = ServiceUtil.returnSuccess(); 222 result.put("refundResult", new Boolean (false)); 223 result.put("refundAmount", new Double (0.00)); 224 result.put("refundRefNum", getReferenceNum(refundResponseDoc)); 225 List messages = getMessageList(refundResponseDoc); 226 if (UtilValidate.isNotEmpty(messages)) { 227 result.put("internalRespMsgs", messages); 228 } 229 return result; 230 } 231 232 return processRefundResponse(refundResponseDoc); 233 } 234 235 public static Map ccReAuth(DispatchContext dctx, Map context) { 236 237 GenericValue orderPaymentPreference = (GenericValue) context.get("orderPaymentPreference"); 238 GenericValue authTransaction = PaymentGatewayServices.getAuthTransaction(orderPaymentPreference); 239 if (authTransaction == null) { 240 return ServiceUtil.returnError("No authorization transaction found; cannot re-auth."); 241 } 242 243 Document reauthRequestDoc = buildSecondaryTxRequest(context, authTransaction.getString("referenceNum"), 244 "RePreAuth", (Double ) context.get("reauthAmount")); 245 246 Document reauthResponseDoc = null; 247 try { 248 reauthResponseDoc = sendRequest(reauthRequestDoc, (String ) context.get("paymentConfig")); 249 } catch (ClearCommerceException cce) { 250 return ServiceUtil.returnError(cce.getMessage()); 251 } 252 253 if (getMessageListMaxSev(reauthResponseDoc) > 4) { 254 Map result = ServiceUtil.returnSuccess(); 255 result.put("reauthResult", new Boolean (false)); 256 result.put("reauthAmount", new Double (0.00)); 257 result.put("reauthRefNum", getReferenceNum(reauthResponseDoc)); 258 List messages = getMessageList(reauthResponseDoc); 259 if (UtilValidate.isNotEmpty(messages)) { 260 result.put("internalRespMsgs", messages); 261 } 262 return result; 263 } 264 265 return processReAuthResponse(reauthResponseDoc); 266 267 } 268 269 private static Map processAuthResponse(Document responseDocument) { 270 271 Element engineDocElement = UtilXml.firstChildElement(responseDocument.getDocumentElement(), "EngineDoc"); 272 Element orderFormElement = UtilXml.firstChildElement(engineDocElement, "OrderFormDoc"); 273 Element transactionElement = UtilXml.firstChildElement(orderFormElement, "Transaction"); 274 Element procResponseElement = UtilXml.firstChildElement(transactionElement, "CardProcResp"); 275 276 Map result = ServiceUtil.returnSuccess(); 277 278 String errorCode = UtilXml.childElementValue(procResponseElement, "CcErrCode"); 279 if ("1".equals(errorCode)) { 280 result.put("authResult", Boolean.valueOf(true)); 281 result.put("authCode", UtilXml.childElementValue(transactionElement, "AuthCode")); 282 283 Element currentTotalsElement = UtilXml.firstChildElement(transactionElement, "CurrentTotals"); 284 Element totalsElement = UtilXml.firstChildElement(currentTotalsElement, "Totals"); 285 String authAmountStr = UtilXml.childElementValue(totalsElement, "Total"); 286 result.put("processAmount", new Double (Double.parseDouble(authAmountStr) / 100)); 287 } else { 288 result.put("authResult", Boolean.valueOf(false)); 289 result.put("processAmount", Double.valueOf("0.00")); 290 } 291 292 result.put("authRefNum", UtilXml.childElementValue(orderFormElement, "Id")); 293 result.put("authFlag", UtilXml.childElementValue(procResponseElement, "Status")); 294 result.put("authMessage", UtilXml.childElementValue(procResponseElement, "CcReturnMsg")); 295 296 String avsCode = UtilXml.childElementValue(procResponseElement, "AvsDisplay"); 298 if (UtilValidate.isNotEmpty(avsCode)) { 299 result.put("avsCode", avsCode); 300 } 301 302 Element fraudInfoElement = UtilXml.firstChildElement(orderFormElement, "FraudInfo"); 304 if (fraudInfoElement != null) { 305 result.put("scoreCode", UtilXml.childElementValue(fraudInfoElement, "TotalScore")); 306 } 307 308 List messages = getMessageList(responseDocument); 309 if (UtilValidate.isNotEmpty(messages)) { 310 result.put("internalRespMsgs", messages); 311 } 312 return result; 313 } 314 315 private static Map processCreditResponse(Document responseDocument) { 316 317 Element engineDocElement = UtilXml.firstChildElement(responseDocument.getDocumentElement(), "EngineDoc"); 318 Element orderFormElement = UtilXml.firstChildElement(engineDocElement, "OrderFormDoc"); 319 Element transactionElement = UtilXml.firstChildElement(orderFormElement, "Transaction"); 320 Element procResponseElement = UtilXml.firstChildElement(transactionElement, "CardProcResp"); 321 322 Map result = ServiceUtil.returnSuccess(); 323 324 String errorCode = UtilXml.childElementValue(procResponseElement, "CcErrCode"); 325 if ("1".equals(errorCode)) { 326 result.put("creditResult", Boolean.valueOf(true)); 327 result.put("creditCode", UtilXml.childElementValue(transactionElement, "AuthCode")); 328 329 Element currentTotalsElement = UtilXml.firstChildElement(transactionElement, "CurrentTotals"); 330 Element totalsElement = UtilXml.firstChildElement(currentTotalsElement, "Totals"); 331 String creditAmountStr = UtilXml.childElementValue(totalsElement, "Total"); 332 result.put("creditAmount", new Double (Double.parseDouble(creditAmountStr) / 100)); 333 } else { 334 result.put("creditResult", Boolean.valueOf(false)); 335 result.put("creditAmount", Double.valueOf("0.00")); 336 } 337 338 result.put("creditRefNum", UtilXml.childElementValue(orderFormElement, "Id")); 339 result.put("creditFlag", UtilXml.childElementValue(procResponseElement, "Status")); 340 result.put("creditMessage", UtilXml.childElementValue(procResponseElement, "CcReturnMsg")); 341 342 List messages = getMessageList(responseDocument); 343 if (UtilValidate.isNotEmpty(messages)) { 344 result.put("internalRespMsgs", messages); 345 } 346 return result; 347 } 348 349 private static Map processCaptureResponse(Document responseDocument) { 350 351 Element engineDocElement = UtilXml.firstChildElement(responseDocument.getDocumentElement(), "EngineDoc"); 352 Element orderFormElement = UtilXml.firstChildElement(engineDocElement, "OrderFormDoc"); 353 Element transactionElement = UtilXml.firstChildElement(orderFormElement, "Transaction"); 354 Element procResponseElement = UtilXml.firstChildElement(transactionElement, "CardProcResp"); 355 356 Map result = ServiceUtil.returnSuccess(); 357 358 String errorCode = UtilXml.childElementValue(procResponseElement, "CcErrCode"); 359 if ("1".equals(errorCode)) { 360 result.put("captureResult", Boolean.valueOf(true)); 361 result.put("captureCode", UtilXml.childElementValue(transactionElement, "AuthCode")); 362 363 Element currentTotalsElement = UtilXml.firstChildElement(transactionElement, "CurrentTotals"); 364 Element totalsElement = UtilXml.firstChildElement(currentTotalsElement, "Totals"); 365 String captureAmountStr = UtilXml.childElementValue(totalsElement, "Total"); 366 result.put("captureAmount", new Double (Double.parseDouble(captureAmountStr) / 100)); 367 } else { 368 result.put("captureResult", Boolean.valueOf(false)); 369 result.put("captureAmount", Double.valueOf("0.00")); 370 } 371 372 result.put("captureRefNum", UtilXml.childElementValue(orderFormElement, "Id")); 373 result.put("captureFlag", UtilXml.childElementValue(procResponseElement, "Status")); 374 result.put("captureMessage", UtilXml.childElementValue(procResponseElement, "CcReturnMsg")); 375 376 List messages = getMessageList(responseDocument); 377 if (UtilValidate.isNotEmpty(messages)) { 378 result.put("internalRespMsgs", messages); 379 } 380 return result; 381 } 382 383 private static Map processReleaseResponse(Document responseDocument) { 384 385 Element engineDocElement = UtilXml.firstChildElement(responseDocument.getDocumentElement(), "EngineDoc"); 386 Element orderFormElement = UtilXml.firstChildElement(engineDocElement, "OrderFormDoc"); 387 Element transactionElement = UtilXml.firstChildElement(orderFormElement, "Transaction"); 388 Element procResponseElement = UtilXml.firstChildElement(transactionElement, "CardProcResp"); 389 390 Map result = ServiceUtil.returnSuccess(); 391 392 String errorCode = UtilXml.childElementValue(procResponseElement, "CcErrCode"); 393 if ("1".equals(errorCode)) { 394 result.put("releaseResult", Boolean.valueOf(true)); 395 result.put("releaseCode", UtilXml.childElementValue(transactionElement, "AuthCode")); 396 397 Element currentTotalsElement = UtilXml.firstChildElement(transactionElement, "CurrentTotals"); 398 Element totalsElement = UtilXml.firstChildElement(currentTotalsElement, "Totals"); 399 String releaseAmountStr = UtilXml.childElementValue(totalsElement, "Total"); 400 result.put("releaseAmount", new Double (Double.parseDouble(releaseAmountStr) / 100)); 401 } else { 402 result.put("releaseResult", Boolean.valueOf(false)); 403 result.put("releaseAmount", Double.valueOf("0.00")); 404 } 405 406 result.put("releaseRefNum", UtilXml.childElementValue(orderFormElement, "Id")); 407 result.put("releaseFlag", UtilXml.childElementValue(procResponseElement, "Status")); 408 result.put("releaseMessage", UtilXml.childElementValue(procResponseElement, "CcReturnMsg")); 409 410 List messages = getMessageList(responseDocument); 411 if (UtilValidate.isNotEmpty(messages)) { 412 result.put("internalRespMsgs", messages); 413 } 414 return result; 415 } 416 417 private static Map processRefundResponse(Document responseDocument) { 418 419 Element engineDocElement = UtilXml.firstChildElement(responseDocument.getDocumentElement(), "EngineDoc"); 420 Element orderFormElement = UtilXml.firstChildElement(engineDocElement, "OrderFormDoc"); 421 Element transactionElement = UtilXml.firstChildElement(orderFormElement, "Transaction"); 422 Element procResponseElement = UtilXml.firstChildElement(transactionElement, "CardProcResp"); 423 424 Map result = ServiceUtil.returnSuccess(); 425 426 String errorCode = UtilXml.childElementValue(procResponseElement, "CcErrCode"); 427 if ("1".equals(errorCode)) { 428 result.put("refundResult", Boolean.valueOf(true)); 429 result.put("refundCode", UtilXml.childElementValue(transactionElement, "AuthCode")); 430 431 Element currentTotalsElement = UtilXml.firstChildElement(transactionElement, "CurrentTotals"); 432 Element totalsElement = UtilXml.firstChildElement(currentTotalsElement, "Totals"); 433 String refundAmountStr = UtilXml.childElementValue(totalsElement, "Total"); 434 result.put("refundAmount", new Double (Double.parseDouble(refundAmountStr) / 100)); 435 } else { 436 result.put("refundResult", Boolean.valueOf(false)); 437 result.put("refundAmount", Double.valueOf("0.00")); 438 } 439 440 result.put("refundRefNum", UtilXml.childElementValue(orderFormElement, "Id")); 441 result.put("refundFlag", UtilXml.childElementValue(procResponseElement, "Status")); 442 result.put("refundMessage", UtilXml.childElementValue(procResponseElement, "CcReturnMsg")); 443 444 List messages = getMessageList(responseDocument); 445 if (UtilValidate.isNotEmpty(messages)) { 446 result.put("internalRespMsgs", messages); 447 } 448 return result; 449 } 450 451 private static Map processReAuthResponse(Document responseDocument) { 452 453 Element engineDocElement = UtilXml.firstChildElement(responseDocument.getDocumentElement(), "EngineDoc"); 454 Element orderFormElement = UtilXml.firstChildElement(engineDocElement, "OrderFormDoc"); 455 Element transactionElement = UtilXml.firstChildElement(orderFormElement, "Transaction"); 456 Element procResponseElement = UtilXml.firstChildElement(transactionElement, "CardProcResp"); 457 458 Map result = ServiceUtil.returnSuccess(); 459 460 String errorCode = UtilXml.childElementValue(procResponseElement, "CcErrCode"); 461 if ("1".equals(errorCode)) { 462 result.put("reauthResult", Boolean.valueOf(true)); 463 result.put("reauthCode", UtilXml.childElementValue(transactionElement, "AuthCode")); 464 465 Element currentTotalsElement = UtilXml.firstChildElement(transactionElement, "CurrentTotals"); 466 Element totalsElement = UtilXml.firstChildElement(currentTotalsElement, "Totals"); 467 String reauthAmountStr = UtilXml.childElementValue(totalsElement, "Total"); 468 result.put("reauthAmount", new Double (Double.parseDouble(reauthAmountStr) / 100)); 469 } else { 470 result.put("reauthResult", Boolean.valueOf(false)); 471 result.put("reauthAmount", Double.valueOf("0.00")); 472 } 473 474 result.put("reauthRefNum", UtilXml.childElementValue(orderFormElement, "Id")); 475 result.put("reauthFlag", UtilXml.childElementValue(procResponseElement, "Status")); 476 result.put("reauthMessage", UtilXml.childElementValue(procResponseElement, "CcReturnMsg")); 477 478 List messages = getMessageList(responseDocument); 479 if (UtilValidate.isNotEmpty(messages)) { 480 result.put("internalRespMsgs", messages); 481 } 482 return result; 483 } 484 485 private static List getMessageList(Document responseDocument) { 486 487 List messageList = new ArrayList (); 488 489 Element engineDocElement = UtilXml.firstChildElement(responseDocument.getDocumentElement(), "EngineDoc"); 490 Element messageListElement = UtilXml.firstChildElement(engineDocElement, "MessageList"); 491 List messageElementList = UtilXml.childElementList(messageListElement, "Message"); 492 if (UtilValidate.isNotEmpty(messageElementList)) { 493 for (Iterator i = messageElementList.iterator(); i.hasNext();) { 494 Element messageElement = (Element ) i.next(); 495 int severity = 0; 496 try { 497 severity = Integer.parseInt(UtilXml.childElementValue(messageElement, "Sev")); 498 } catch (NumberFormatException nfe) { 499 Debug.logError("Error parsing message severity: " + nfe.getMessage(), module); 500 severity = 9; 501 } 502 String message = "[" + UtilXml.childElementValue(messageElement, "Audience") + "] " + 503 UtilXml.childElementValue(messageElement, "Text") + " (" + severity + ")"; 504 messageList.add(message); 505 } 506 } 507 508 return messageList; 509 } 510 511 private static int getMessageListMaxSev(Document responseDocument) { 512 513 int maxSev = 0; 514 515 Element engineDocElement = UtilXml.firstChildElement(responseDocument.getDocumentElement(), "EngineDoc"); 516 Element messageListElement = UtilXml.firstChildElement(engineDocElement, "MessageList"); 517 String maxSevStr = UtilXml.childElementValue(messageListElement, "MaxSev"); 518 if (UtilValidate.isNotEmpty(maxSevStr)) { 519 try { 520 maxSev = Integer.parseInt(maxSevStr); 521 } catch (NumberFormatException nfe) { 522 Debug.logError("Error parsing MaxSev: " + nfe.getMessage(), module); 523 maxSev = 9; 524 } 525 } 526 return maxSev; 527 } 528 529 private static String getReferenceNum(Document responseDocument) { 530 String referenceNum = null; 531 Element engineDocElement = UtilXml.firstChildElement(responseDocument.getDocumentElement(), "EngineDoc"); 532 if (engineDocElement != null) { 533 Element orderFormElement = UtilXml.firstChildElement(engineDocElement, "OrderFormDoc"); 534 if (orderFormElement != null) { 535 referenceNum = UtilXml.childElementValue(orderFormElement, "Id"); 536 } 537 } 538 return referenceNum; 539 } 540 541 private static Document buildPrimaryTxRequest(Map context, String type, Double amount, String refNum) { 542 543 String paymentConfig = (String ) context.get("paymentConfig"); 544 if (UtilValidate.isEmpty(paymentConfig)) { 545 paymentConfig = "payment.properties"; 546 } 547 548 Document requestDocument = createRequestDocument(paymentConfig); 549 550 Element engineDocElement = UtilXml.firstChildElement(requestDocument.getDocumentElement(), "EngineDoc"); 551 Element orderFormDocElement = UtilXml.firstChildElement(engineDocElement, "OrderFormDoc"); 552 553 UtilXml.addChildElementValue(orderFormDocElement, "Comments", refNum, requestDocument); 555 556 Element consumerElement = UtilXml.addChildElement(orderFormDocElement, "Consumer", requestDocument); 557 558 GenericValue billToEmail = (GenericValue) context.get("billToEmail"); 560 if (billToEmail != null) { 561 UtilXml.addChildElementValue(consumerElement, "Email", billToEmail.getString("infoString"), requestDocument); 562 } 563 564 GenericValue creditCard = (GenericValue) context.get("creditCard"); 566 567 boolean enableCVM = UtilProperties.propertyValueEqualsIgnoreCase(paymentConfig, "payment.clearcommerce.enableCVM", "Y"); 568 String cardSecurityCode = enableCVM ? (String ) context.get("cardSecurityCode") : null; 569 570 String localCode = UtilProperties.getPropertyValue(paymentConfig, "payment.clearcommerce.localeCode", "840"); 572 573 appendPaymentMechNode(consumerElement, creditCard, cardSecurityCode, localCode); 574 575 GenericValue billingAddress = (GenericValue) context.get("billingAddress"); 577 if (billingAddress != null) { 578 Element billToElement = UtilXml.addChildElement(consumerElement, "BillTo", requestDocument); 579 Element billToLocationElement = UtilXml.addChildElement(billToElement, "Location", requestDocument); 580 appendAddressNode(billToLocationElement, billingAddress); 581 } 582 583 GenericValue shippingAddress = (GenericValue) context.get("shippingAddress"); 585 if (shippingAddress != null) { 586 Element shipToElement = UtilXml.addChildElement(consumerElement, "ShipTo", requestDocument); 587 Element shipToLocationElement = UtilXml.addChildElement(shipToElement, "Location", requestDocument); 588 appendAddressNode(shipToLocationElement, shippingAddress); 589 } 590 591 String currencyCode = UtilProperties.getPropertyValue(paymentConfig, "payment.clearcommerce.currencyCode", "840"); 593 594 appendTransactionNode(orderFormDocElement, type, amount, currencyCode); 596 597 599 return requestDocument; 600 } 601 602 private static Document buildSecondaryTxRequest(Map context, String id, String type, Double amount) { 603 604 String paymentConfig = (String ) context.get("paymentConfig"); 605 if (UtilValidate.isEmpty(paymentConfig)) { 606 paymentConfig = "payment.properties"; 607 } 608 609 Document requestDocument = createRequestDocument(paymentConfig); 610 611 Element engineDocElement = UtilXml.firstChildElement(requestDocument.getDocumentElement(), "EngineDoc"); 612 Element orderFormDocElement = UtilXml.firstChildElement(engineDocElement, "OrderFormDoc"); 613 UtilXml.addChildElementValue(orderFormDocElement, "Id", id, requestDocument); 614 615 String currencyCode = UtilProperties.getPropertyValue(paymentConfig, "payment.clearcommerce.currencyCode", "840"); 617 618 appendTransactionNode(orderFormDocElement, type, amount, currencyCode); 619 620 return requestDocument; 621 } 622 623 private static void appendPaymentMechNode(Element element, GenericValue creditCard, String cardSecurityCode, String localeCode) { 624 625 Document document = element.getOwnerDocument(); 626 627 Element paymentMechElement = UtilXml.addChildElement(element, "PaymentMech", document); 628 Element creditCardElement = UtilXml.addChildElement(paymentMechElement, "CreditCard", document); 629 630 UtilXml.addChildElementValue(creditCardElement, "Number", creditCard.getString("cardNumber"), document); 631 632 String expDate = creditCard.getString("expireDate"); 633 Element expiresElement = UtilXml.addChildElementValue(creditCardElement, "Expires", 634 expDate.substring(0, 3) + expDate.substring(5), document); 635 expiresElement.setAttribute("DataType", "ExpirationDate"); 636 expiresElement.setAttribute("Locale", localeCode); 637 638 if (UtilValidate.isNotEmpty(cardSecurityCode)) { 639 if (cardSecurityCode.length() < 4) { 641 while (cardSecurityCode.length() < 4) { 642 cardSecurityCode = cardSecurityCode + " "; 643 } 644 } else if (cardSecurityCode.length() > 4) { 645 cardSecurityCode = cardSecurityCode.substring(0, 4); 646 } 647 UtilXml.addChildElementValue(creditCardElement, "Cvv2Val", cardSecurityCode, document); 648 UtilXml.addChildElementValue(creditCardElement, "Cvv2Indicator", "1", document); 649 } 650 } 651 652 private static void appendAddressNode(Element element, GenericValue address) { 653 654 Document document = element.getOwnerDocument(); 655 656 Element addressElement = UtilXml.addChildElement(element, "Address", document); 657 658 UtilXml.addChildElementValue(addressElement, "Name", address.getString("toName"), document); 659 UtilXml.addChildElementValue(addressElement, "Street1", address.getString("address1"), document); 660 UtilXml.addChildElementValue(addressElement, "Street2", address.getString("address2"), document); 661 UtilXml.addChildElementValue(addressElement, "City", address.getString("city"), document); 662 UtilXml.addChildElementValue(addressElement, "StateProv", address.getString("stateProvinceGeoId"), document); 663 UtilXml.addChildElementValue(addressElement, "PostalCode", address.getString("postalCode"), document); 664 665 String countryGeoId = address.getString("countryGeoId"); 666 if (UtilValidate.isNotEmpty(countryGeoId)) { 667 try { 668 GenericValue countryGeo = address.getRelatedOneCache("CountryGeo"); 669 UtilXml.addChildElementValue(addressElement, "Country", countryGeo.getString("geoSecCode"), document); 670 } catch (GenericEntityException gee) { 671 Debug.log(gee, "Error finding related Geo for countryGeoId: " + countryGeoId, module); 672 } 673 } 674 } 675 676 private static void appendTransactionNode(Element element, String type, Double amount, String currencyCode) { 677 678 Document document = element.getOwnerDocument(); 679 680 Element transactionElement = UtilXml.addChildElement(element, "Transaction", document); 681 UtilXml.addChildElementValue(transactionElement, "Type", type, document); 682 683 if (amount != null) { 685 Element currentTotalsElement = UtilXml.addChildElement(transactionElement, "CurrentTotals", document); 686 Element totalsElement = UtilXml.addChildElement(currentTotalsElement, "Totals", document); 687 688 String totalString = new DecimalFormat ("#").format(amount.doubleValue() * 100); 691 692 Element totalElement = UtilXml.addChildElementValue(totalsElement, "Total", totalString, document); 693 totalElement.setAttribute("DataType", "Money"); 694 totalElement.setAttribute("Currency", currencyCode); 695 } 696 } 697 698 private static Document createRequestDocument(String paymentConfig) { 699 700 Document requestDocument = UtilXml.makeEmptyXmlDocument("EngineDocList"); 702 Element engineDocListElement = requestDocument.getDocumentElement(); 703 UtilXml.addChildElementValue(engineDocListElement, "DocVersion", "1.0", requestDocument); 704 705 Element engineDocElement = UtilXml.addChildElement(engineDocListElement, "EngineDoc", requestDocument); 707 UtilXml.addChildElementValue(engineDocElement, "ContentType", "OrderFormDoc", requestDocument); 708 709 String sourceId = UtilProperties.getPropertyValue(paymentConfig, "payment.clearcommerce.sourceId"); 710 if (UtilValidate.isNotEmpty(sourceId)) { 711 UtilXml.addChildElementValue(engineDocElement, "SourceId", sourceId, requestDocument); 712 } 713 714 String groupId = UtilProperties.getPropertyValue(paymentConfig, "payment.clearcommerce.groupId"); 715 if (UtilValidate.isNotEmpty(groupId)) { 716 UtilXml.addChildElementValue(engineDocElement, "GroupId", groupId, requestDocument); 717 } 718 719 Element userElement = UtilXml.addChildElement(engineDocElement, "User", requestDocument); 721 UtilXml.addChildElementValue(userElement, "Name", 722 UtilProperties.getPropertyValue(paymentConfig, "payment.clearcommerce.username", ""), requestDocument); 723 UtilXml.addChildElementValue(userElement, "Password", 724 UtilProperties.getPropertyValue(paymentConfig, "payment.clearcommerce.password", ""), requestDocument); 725 UtilXml.addChildElementValue(userElement, "Alias", 726 UtilProperties.getPropertyValue(paymentConfig, "payment.clearcommerce.alias", ""), requestDocument); 727 728 String effectiveAlias = UtilProperties.getPropertyValue(paymentConfig, "payment.clearcommerce.effectiveAlias"); 729 if (UtilValidate.isNotEmpty(effectiveAlias)) { 730 UtilXml.addChildElementValue(userElement, "EffectiveAlias", effectiveAlias, requestDocument); 731 } 732 733 Element instructionsElement = UtilXml.addChildElement(engineDocElement, "Instructions", requestDocument); 735 736 String pipeline = "PaymentNoFraud"; 737 if (UtilProperties.propertyValueEqualsIgnoreCase(paymentConfig, "payment.clearcommerce.enableFraudShield", "Y")) { 738 pipeline = "Payment"; 739 } 740 UtilXml.addChildElementValue(instructionsElement, "Pipeline", pipeline, requestDocument); 741 742 Element orderFormDocElement = UtilXml.addChildElement(engineDocElement, "OrderFormDoc", requestDocument); 744 745 String mode = UtilProperties.getPropertyValue(paymentConfig, "payment.clearcommerce.processMode", "P"); 747 UtilXml.addChildElementValue(orderFormDocElement, "Mode", mode, requestDocument); 748 749 return requestDocument; 750 } 751 752 private static Document sendRequest(Document requestDocument, String paymentConfig) throws ClearCommerceException { 753 754 if (UtilValidate.isEmpty(paymentConfig)) { 755 paymentConfig = "payment.properties"; 756 } 757 758 String serverURL = UtilProperties.getPropertyValue(paymentConfig, "payment.clearcommerce.serverURL"); 759 if (UtilValidate.isEmpty(serverURL)) { 760 throw new ClearCommerceException("Missing server URL; check your ClearCommerce configuration"); 761 } 762 if (Debug.verboseOn()) { 763 Debug.logVerbose("ClearCommerce server URL: " + serverURL, module); 764 } 765 766 OutputStream os = new ByteArrayOutputStream (); 767 768 OutputFormat format = new OutputFormat(); 769 format.setOmitDocumentType(true); 770 format.setOmitXMLDeclaration(true); 771 format.setIndenting(false); 772 773 XMLSerializer serializer = new XMLSerializer(os, format); 774 try { 775 serializer.asDOMSerializer(); 776 serializer.serialize(requestDocument.getDocumentElement()); 777 } catch (IOException ioe) { 778 throw new ClearCommerceException("Error serializing requestDocument: " + ioe.getMessage()); 779 } 780 781 String xmlString = os.toString(); 782 783 if (Debug.verboseOn()) { 784 Debug.logVerbose("ClearCommerce XML request string: " + xmlString, module); 785 } 786 787 HttpClient http = new HttpClient(serverURL); 788 http.setParameter("CLRCMRC_XML", xmlString); 789 790 String response = null; 791 try { 792 response = http.post(); 793 } catch (HttpClientException hce) { 794 Debug.log(hce, module); 795 throw new ClearCommerceException("ClearCommerce connection problem", hce); 796 } 797 798 803 Document responseDocument = null; 804 try { 805 responseDocument = UtilXml.readXmlDocument(response, false); 806 } catch (SAXException se) { 807 throw new ClearCommerceException("Error reading response Document from a String: " + se.getMessage()); 808 } catch (ParserConfigurationException pce) { 809 throw new ClearCommerceException("Error reading response Document from a String: " + pce.getMessage()); 810 } catch (IOException ioe) { 811 throw new ClearCommerceException("Error reading response Document from a String: " + ioe.getMessage()); 812 } 813 814 return responseDocument; 815 } 816 817 } 818 819 class ClearCommerceException extends GeneralException { 820 821 ClearCommerceException() { 822 super(); 823 } 824 825 826 ClearCommerceException(String msg) { 827 super(msg); 828 } 829 830 831 ClearCommerceException(Throwable t) { 832 super(t); 833 } 834 835 836 ClearCommerceException(String msg, Throwable t) { 837 super(msg, t); 838 } 839 } 840 841 | Popular Tags |