use of org.broadleafcommerce.common.payment.dto.PaymentRequestDTO in project BroadleafCommerce by BroadleafCommerce.
the class OrderToPaymentRequestDTOServiceImpl method translatePaymentTransaction.
@Override
public PaymentRequestDTO translatePaymentTransaction(Money transactionAmount, PaymentTransaction paymentTransaction, boolean autoCalculateFinalPaymentTotals) {
paymentTransaction = refreshTransaction(paymentTransaction);
if (LOG.isTraceEnabled()) {
LOG.trace(String.format("Translating Payment Transaction (ID:%s) into a PaymentRequestDTO for the configured " + "gateway.", paymentTransaction.getId()));
}
// Will set the full amount to be charged on the transaction total/subtotal and not worry about shipping/tax breakdown
PaymentRequestDTO requestDTO = new PaymentRequestDTO().transactionTotal(transactionAmount.getAmount().toPlainString()).orderSubtotal(transactionAmount.getAmount().toPlainString()).shippingTotal(ZERO_TOTAL).taxTotal(ZERO_TOTAL).orderCurrencyCode(paymentTransaction.getOrderPayment().getCurrency().getCurrencyCode()).orderId(paymentTransaction.getOrderPayment().getOrder().getId().toString());
Order order = paymentTransaction.getOrderPayment().getOrder();
populateCustomerInfo(order, requestDTO);
populateShipTo(order, requestDTO);
populateBillTo(order, requestDTO);
if (autoCalculateFinalPaymentTotals) {
populateTotals(order, requestDTO);
populateDefaultLineItemsAndSubtotal(order, requestDTO);
}
// Copy Additional Fields from PaymentTransaction into the Request DTO.
// This will contain any gateway specific information needed to perform actions on this transaction
Map<String, String> additionalFields = paymentTransaction.getAdditionalFields();
for (String key : additionalFields.keySet()) {
requestDTO.additionalField(key, additionalFields.get(key));
}
return requestDTO;
}
use of org.broadleafcommerce.common.payment.dto.PaymentRequestDTO in project BroadleafCommerce by BroadleafCommerce.
the class OrderToPaymentRequestDTOServiceImpl method translateOrder.
@Override
public PaymentRequestDTO translateOrder(Order order) {
if (order != null) {
final Long id = order.getId();
final BroadleafCurrency currency = order.getCurrency();
PaymentRequestDTO requestDTO = new PaymentRequestDTO().orderId(id.toString());
if (LOG.isTraceEnabled()) {
LOG.trace(String.format("Translating Order (ID:%s) into a PaymentRequestDTO for the configured " + "gateway.", id));
}
if (currency != null) {
requestDTO.orderCurrencyCode(currency.getCurrencyCode());
}
populateCustomerInfo(order, requestDTO);
populateShipTo(order, requestDTO);
populateBillTo(order, requestDTO);
populateTotals(order, requestDTO);
populateDefaultLineItemsAndSubtotal(order, requestDTO);
return requestDTO;
}
return null;
}
use of org.broadleafcommerce.common.payment.dto.PaymentRequestDTO in project BroadleafCommerce by BroadleafCommerce.
the class OrderPaymentConfirmationStrategyImpl method confirmTransactionInternal.
protected PaymentResponseDTO confirmTransactionInternal(PaymentTransaction tx, ProcessContext<CheckoutSeed> context, boolean isCheckout) throws PaymentException, WorkflowException, CheckoutException {
// Cannot confirm anything here if there is no provider
if (paymentConfigurationServiceProvider == null) {
String msg = "There are unconfirmed payment transactions on this payment but no payment gateway" + " configuration or transaction confirmation service configured";
LOG.error(msg);
throw new CheckoutException(msg, context.getSeedData());
}
OrderPayment payment = tx.getOrderPayment();
PaymentGatewayConfigurationService cfg = paymentConfigurationServiceProvider.getGatewayConfigurationService(tx.getOrderPayment().getGatewayType());
PaymentResponseDTO responseDTO = null;
// Auto-calculate totals and line items to send to the gateway when in a "Checkout Payment flow"
// (i.e. where the transaction is part of a final payment that is meant to be charged last at checkout: UNCONFIRMED -> AUTHORIZE or UNCONFIRMED -> AUTHORIZE_AND_CAPTURE)
// Note: the total for the request cannot be auto-calculated if the order contains multiple final payments (i.e. multiple credit cards)
PaymentRequestDTO confirmationRequest;
if (payment.isFinalPayment() && !orderContainsMultipleFinalPayments(payment.getOrder())) {
confirmationRequest = orderToPaymentRequestService.translatePaymentTransaction(payment.getAmount(), tx, true);
} else {
confirmationRequest = orderToPaymentRequestService.translatePaymentTransaction(payment.getAmount(), tx);
}
populateBillingAddressOnRequest(confirmationRequest, payment);
populateCustomerOnRequest(confirmationRequest, payment);
populateShippingAddressOnRequest(confirmationRequest, payment);
if (isCheckout && enablePendingPaymentsOnCheckoutConfirmation()) {
responseDTO = constructPendingTransaction(payment.getType(), payment.getGatewayType(), confirmationRequest);
} else {
if (PaymentType.CREDIT_CARD.equals(payment.getType())) {
// Handles the PCI-Compliant Scenario where you have an UNCONFIRMED CREDIT_CARD payment on the order.
// This can happen if you send the Credit Card directly to Broadleaf or you use a Digital Wallet solution like MasterPass.
// The Actual Credit Card PAN is stored in blSecurePU and will need to be sent to the Payment Gateway for processing.
populateCreditCardOnRequest(confirmationRequest, payment);
if (cfg.getConfiguration().isPerformAuthorizeAndCapture()) {
responseDTO = cfg.getTransactionService().authorizeAndCapture(confirmationRequest);
} else {
responseDTO = cfg.getTransactionService().authorize(confirmationRequest);
}
} else {
// This handles the THIRD_PARTY_ACCOUNT scenario (like PayPal Express Checkout) where
// the transaction just needs to be confirmed with the Gateway
responseDTO = cfg.getTransactionConfirmationService().confirmTransaction(confirmationRequest);
}
}
return responseDTO;
}
use of org.broadleafcommerce.common.payment.dto.PaymentRequestDTO in project BroadleafCommerce by BroadleafCommerce.
the class TransparentRedirectCreditCardFormProcessor method getInjectedModelAndTagAttributes.
@Override
public BroadleafTemplateModelModifierDTO getInjectedModelAndTagAttributes(String rootTagName, Map<String, String> rootTagAttributes, BroadleafTemplateContext context) {
PaymentRequestDTO requestDTO = (PaymentRequestDTO) context.parseExpression(rootTagAttributes.get("paymentRequestDTO"));
Map<String, Map<String, String>> formParameters = new HashMap<>();
Map<String, String> configurationSettings = new HashMap<>();
// Create the configuration settings map to pass into the payment module
Map<String, String> keysToKeep = new HashMap<>();
for (String key : rootTagAttributes.keySet()) {
if (key.startsWith("config-")) {
final int trimLength = "config-".length();
String configParam = key.substring(trimLength);
configurationSettings.put(configParam, rootTagAttributes.get(key));
} else {
keysToKeep.put(key, rootTagAttributes.get(key));
}
}
keysToKeep.remove("paymentRequestDTO");
try {
extensionManager.getProxy().createTransparentRedirectForm(formParameters, requestDTO, configurationSettings);
} catch (PaymentException e) {
throw new RuntimeException("Unable to Create the Transparent Redirect Form", e);
}
StringBuilder formActionKey = new StringBuilder("formActionKey");
StringBuilder formHiddenParamsKey = new StringBuilder("formHiddenParamsKey");
extensionManager.getProxy().setFormActionKey(formActionKey);
extensionManager.getProxy().setFormHiddenParamsKey(formHiddenParamsKey);
// Change the action attribute on the form to the Payment Gateways Endpoint
String actionUrl = "";
Map<String, String> actionValue = formParameters.get(formActionKey.toString());
if (actionValue != null && actionValue.size() > 0) {
String key = (String) actionValue.keySet().toArray()[0];
actionUrl = actionValue.get(key);
}
keysToKeep.put("action", actionUrl);
BroadleafTemplateModel model = context.createModel();
// Append any hidden fields necessary for the Transparent Redirect
Map<String, String> hiddenFields = formParameters.get(formHiddenParamsKey.toString());
if (MapUtils.isNotEmpty(hiddenFields)) {
for (String key : hiddenFields.keySet()) {
Map<String, String> attributes = new HashMap<>();
attributes.put("type", "hidden");
attributes.put("name", key);
attributes.put("value", hiddenFields.get(key));
BroadleafTemplateElement input = context.createStandaloneElement("input", attributes, true);
model.addElement(input);
}
}
return new BroadleafTemplateModelModifierDTO(model, keysToKeep, "form");
}
use of org.broadleafcommerce.common.payment.dto.PaymentRequestDTO in project BroadleafCommerce by BroadleafCommerce.
the class ConfirmPaymentsRollbackHandler method rollbackState.
@Override
public void rollbackState(Activity<ProcessContext<CheckoutSeed>> activity, ProcessContext<CheckoutSeed> processContext, Map<String, Object> stateConfiguration) throws RollbackFailureException {
CheckoutSeed seed = processContext.getSeedData();
if (paymentConfigurationServiceProvider == null) {
throw new RollbackFailureException("There is no rollback service configured for the payment gateway configuration, cannot rollback unconfirmed" + " payments");
}
Map<OrderPayment, PaymentTransaction> rollbackResponseTransactions = new HashMap<>();
Collection<PaymentTransaction> transactions = (Collection<PaymentTransaction>) stateConfiguration.get(ValidateAndConfirmPaymentActivity.ROLLBACK_TRANSACTIONS);
if (CollectionUtils.isNotEmpty(transactions)) {
for (PaymentTransaction tx : transactions) {
PaymentRequestDTO rollbackRequest = transactionToPaymentRequestDTOService.translatePaymentTransaction(tx.getAmount(), tx);
PaymentGatewayConfigurationService cfg = paymentConfigurationServiceProvider.getGatewayConfigurationService(tx.getOrderPayment().getGatewayType());
try {
PaymentResponseDTO responseDTO = null;
if (PaymentTransactionType.AUTHORIZE.equals(tx.getType())) {
if (cfg.getRollbackService() != null) {
responseDTO = cfg.getRollbackService().rollbackAuthorize(rollbackRequest);
}
} else if (PaymentTransactionType.AUTHORIZE_AND_CAPTURE.equals(tx.getType())) {
if (cfg.getRollbackService() != null) {
responseDTO = cfg.getRollbackService().rollbackAuthorizeAndCapture(rollbackRequest);
}
} else {
LOG.warn("The transaction with id " + tx.getId() + " will NOT be rolled back as it is not an AUTHORIZE or AUTHORIZE_AND_CAPTURE transaction but is" + " of type " + tx.getType() + ". If you need to roll back transactions of this type then provide a customized rollback handler for" + " confirming transactions.");
}
if (responseDTO != null) {
PaymentTransaction transaction = orderPaymentService.createTransaction();
transaction.setAmount(responseDTO.getAmount());
transaction.setRawResponse(responseDTO.getRawResponse());
transaction.setSuccess(responseDTO.isSuccessful());
transaction.setType(responseDTO.getPaymentTransactionType());
transaction.setParentTransaction(tx);
transaction.setOrderPayment(tx.getOrderPayment());
transaction.setAdditionalFields(responseDTO.getResponseMap());
rollbackResponseTransactions.put(tx.getOrderPayment(), transaction);
if (!responseDTO.isSuccessful()) {
LOG.fatal("Unable to rollback transaction with id " + tx.getId() + ". The call was unsuccessful with" + " raw response: " + responseDTO.getRawResponse());
}
}
} catch (PaymentException e) {
throw new RollbackFailureException("The transaction with id " + tx.getId() + " encountered and exception when it was attempted to roll back" + " its confirmation", e);
}
}
Order order = seed.getOrder();
List<OrderPayment> paymentsToInvalidate = new ArrayList<>();
// Add the new rollback transactions to the appropriate payment and mark the payment as invalid.
// If there was a failed transaction rolling back we will need to throw a RollbackFailureException after saving the
// Transaction Response to the DB
boolean rollbackFailure = false;
for (OrderPayment payment : order.getPayments()) {
if (rollbackResponseTransactions.containsKey(payment)) {
PaymentTransaction rollbackTX = rollbackResponseTransactions.get(payment);
payment.addTransaction(rollbackTX);
payment = orderPaymentService.save(payment);
paymentsToInvalidate.add(payment);
if (!rollbackTX.getSuccess()) {
rollbackFailure = true;
}
}
}
for (OrderPayment payment : paymentsToInvalidate) {
paymentGatewayCheckoutService.markPaymentAsInvalid(payment.getId());
orderPaymentService.save(payment);
}
if (rollbackFailure) {
throw new RollbackFailureException("The ConfirmPaymentsRollbackHandler encountered and exception when it " + "attempted to roll back a transaction on one of the payments. Please see LOG for details.");
}
try {
processContext.getSeedData().setOrder(orderService.save(order, false));
} catch (PricingException e) {
throw new RollbackFailureException("Unable to save the order with invalidated payments.");
}
}
}
Aggregations