Search in sources :

Example 1 with PaymentResponseDTO

use of org.broadleafcommerce.common.payment.dto.PaymentResponseDTO in project BroadleafCommerce by BroadleafCommerce.

the class DefaultPaymentGatewayCheckoutService method applyPaymentToOrder.

@Override
public Long applyPaymentToOrder(PaymentResponseDTO responseDTO, PaymentGatewayConfiguration config) {
    // Payments can ONLY be parsed into Order Payments if they are 'valid'
    if (!responseDTO.isValid()) {
        throw new IllegalArgumentException("Invalid payment responses cannot be parsed into the order payment domain");
    }
    if (config == null) {
        throw new IllegalArgumentException("Config service cannot be null");
    }
    Long orderId = Long.parseLong(responseDTO.getOrderId());
    Order order = orderService.findOrderById(orderId);
    if (!OrderStatus.IN_PROCESS.equals(order.getStatus()) && !OrderStatus.CSR_OWNED.equals(order.getStatus()) && !OrderStatus.QUOTE.equals(order.getStatus())) {
        throw new IllegalArgumentException("Cannot apply another payment to an Order that is not IN_PROCESS or CSR_OWNED");
    }
    Customer customer = order.getCustomer();
    if (customer.isAnonymous()) {
        GatewayCustomerDTO<PaymentResponseDTO> gatewayCustomer = responseDTO.getCustomer();
        if (StringUtils.isEmpty(customer.getFirstName()) && gatewayCustomer != null) {
            customer.setFirstName(gatewayCustomer.getFirstName());
        }
        if (StringUtils.isEmpty(customer.getLastName()) && gatewayCustomer != null) {
            customer.setLastName(gatewayCustomer.getLastName());
        }
        if (StringUtils.isEmpty(customer.getEmailAddress()) && gatewayCustomer != null) {
            customer.setEmailAddress(gatewayCustomer.getEmail());
        }
    }
    // If the gateway sends back an email address and the order does not contain one, set it.
    GatewayCustomerDTO<PaymentResponseDTO> gatewayCustomer = responseDTO.getCustomer();
    if (order.getEmailAddress() == null && gatewayCustomer != null) {
        order.setEmailAddress(gatewayCustomer.getEmail());
    }
    // If the gateway sends back Shipping Information, we will save that to the first shippable fulfillment group.
    dtoToEntityService.populateShippingInfo(responseDTO, order);
    // ALWAYS create a new order payment for the payment that comes in. Invalid payments should be cleaned up by
    // invoking {@link #markPaymentAsInvalid}.
    OrderPayment payment = orderPaymentService.create();
    payment.setType(responseDTO.getPaymentType());
    payment.setPaymentGatewayType(responseDTO.getPaymentGatewayType());
    payment.setAmount(responseDTO.getAmount());
    // If this gateway does not support multiple payments then mark all of the existing payments
    // as invalid before adding the new one
    List<OrderPayment> paymentsToInvalidate = new ArrayList<OrderPayment>();
    Address tempBillingAddress = null;
    if (!config.handlesMultiplePayments()) {
        PaymentGatewayType gateway = config.getGatewayType();
        for (OrderPayment p : order.getPayments()) {
            // - The payment being added has the same gateway type of an existing one.
            if (PaymentGatewayType.TEMPORARY.equals(p.getGatewayType()) || (p.isFinalPayment() && payment.isFinalPayment()) || (p.getGatewayType() != null && p.getGatewayType().equals(gateway))) {
                paymentsToInvalidate.add(p);
                if (PaymentGatewayType.TEMPORARY.equals(p.getGatewayType())) {
                    tempBillingAddress = p.getBillingAddress();
                }
            }
        }
    }
    for (OrderPayment invalid : paymentsToInvalidate) {
        // 2
        markPaymentAsInvalid(invalid.getId());
    }
    // The billing address that will be saved on the order will be parsed off the
    // Response DTO sent back from the Gateway as it may have Address Verification or Standardization.
    // If you do not wish to use the Billing Address coming back from the Gateway, you can override the
    // populateBillingInfo() method or set the useBillingAddressFromGateway property.
    dtoToEntityService.populateBillingInfo(responseDTO, payment, tempBillingAddress, isUseBillingAddressFromGateway());
    // Create the transaction for the payment
    PaymentTransaction transaction = orderPaymentService.createTransaction();
    transaction.setAmount(responseDTO.getAmount());
    transaction.setRawResponse(responseDTO.getRawResponse());
    transaction.setSuccess(responseDTO.isSuccessful());
    transaction.setType(responseDTO.getPaymentTransactionType());
    for (Entry<String, String> entry : responseDTO.getResponseMap().entrySet()) {
        transaction.getAdditionalFields().put(entry.getKey(), entry.getValue());
    }
    // Set the Credit Card Info on the Additional Fields Map
    if (responseDTO.getCreditCard() != null && responseDTO.getCreditCard().creditCardPopulated()) {
        transaction.getAdditionalFields().put(PaymentAdditionalFieldType.NAME_ON_CARD.getType(), responseDTO.getCreditCard().getCreditCardHolderName());
        transaction.getAdditionalFields().put(PaymentAdditionalFieldType.CARD_TYPE.getType(), responseDTO.getCreditCard().getCreditCardType());
        transaction.getAdditionalFields().put(PaymentAdditionalFieldType.EXP_DATE.getType(), responseDTO.getCreditCard().getCreditCardExpDate());
        transaction.getAdditionalFields().put(PaymentAdditionalFieldType.LAST_FOUR.getType(), responseDTO.getCreditCard().getCreditCardLastFour());
    }
    // TODO: validate that this particular type of transaction can be added to the payment (there might already
    // be an AUTHORIZE transaction, for instance)
    // Persist the order payment as well as its transaction
    payment.setOrder(order);
    transaction.setOrderPayment(payment);
    payment.addTransaction(transaction);
    payment = orderPaymentService.save(payment);
    if (transaction.getSuccess()) {
        orderService.addPaymentToOrder(order, payment, null);
    } else {
        // We will have to mark the entire payment as invalid and boot the user to re-enter their
        // billing info and payment information as there may be an error either with the billing address/or credit card
        handleUnsuccessfulTransaction(payment);
    }
    return payment.getId();
}
Also used : Order(org.broadleafcommerce.core.order.domain.Order) Address(org.broadleafcommerce.profile.core.domain.Address) Customer(org.broadleafcommerce.profile.core.domain.Customer) ArrayList(java.util.ArrayList) OrderPayment(org.broadleafcommerce.core.payment.domain.OrderPayment) PaymentGatewayType(org.broadleafcommerce.common.payment.PaymentGatewayType) PaymentTransaction(org.broadleafcommerce.core.payment.domain.PaymentTransaction) PaymentResponseDTO(org.broadleafcommerce.common.payment.dto.PaymentResponseDTO)

Example 2 with PaymentResponseDTO

use of org.broadleafcommerce.common.payment.dto.PaymentResponseDTO in project BroadleafCommerce by BroadleafCommerce.

the class PaymentResponseDTOToEntityServiceImpl method populateShippingInfo.

@Override
public void populateShippingInfo(PaymentResponseDTO responseDTO, Order order) {
    FulfillmentGroup shippableFulfillmentGroup = fulfillmentGroupService.getFirstShippableFulfillmentGroup(order);
    if (responseDTO.getShipTo() != null && responseDTO.getShipTo().addressPopulated() && shippableFulfillmentGroup != null) {
        Address shippingAddress = addressService.create();
        AddressDTO<PaymentResponseDTO> shipToDTO = responseDTO.getShipTo();
        populateAddressInfo(shipToDTO, shippingAddress);
        shippableFulfillmentGroup = fulfillmentGroupService.findFulfillmentGroupById(shippableFulfillmentGroup.getId());
        if (shippableFulfillmentGroup != null) {
            shippableFulfillmentGroup.setAddress(shippingAddress);
            fulfillmentGroupService.save(shippableFulfillmentGroup);
        }
    }
}
Also used : Address(org.broadleafcommerce.profile.core.domain.Address) FulfillmentGroup(org.broadleafcommerce.core.order.domain.FulfillmentGroup) PaymentResponseDTO(org.broadleafcommerce.common.payment.dto.PaymentResponseDTO)

Example 3 with PaymentResponseDTO

use of org.broadleafcommerce.common.payment.dto.PaymentResponseDTO in project BroadleafCommerce by BroadleafCommerce.

the class NullIntegrationGatewayTransactionServiceImpl method refund.

@Override
public PaymentResponseDTO refund(PaymentRequestDTO paymentRequestDTO) throws PaymentException {
    PaymentResponseDTO responseDTO = new PaymentResponseDTO(PaymentType.CREDIT_CARD, NullIntegrationGatewayType.NULL_INTEGRATION_GATEWAY);
    responseDTO.valid(true).paymentTransactionType(PaymentTransactionType.REFUND).amount(new Money(paymentRequestDTO.getTransactionTotal())).rawResponse("Successful Refund").successful(true);
    return responseDTO;
}
Also used : Money(org.broadleafcommerce.common.money.Money) PaymentResponseDTO(org.broadleafcommerce.common.payment.dto.PaymentResponseDTO)

Example 4 with PaymentResponseDTO

use of org.broadleafcommerce.common.payment.dto.PaymentResponseDTO in project BroadleafCommerce by BroadleafCommerce.

the class NullIntegrationGatewayTransactionServiceImpl method capture.

/**
 * for the test implementation, and in order to test different failed response scenarios, check for the presence of a "desired outcome"
 * entry in the request's additional fields
 */
@Override
public PaymentResponseDTO capture(PaymentRequestDTO paymentRequestDTO) throws PaymentException {
    PaymentResponseDTO responseDTO = new PaymentResponseDTO(PaymentType.THIRD_PARTY_ACCOUNT, NullIntegrationGatewayType.NULL_INTEGRATION_GATEWAY);
    responseDTO.paymentTransactionType(PaymentTransactionType.AUTHORIZE_AND_CAPTURE);
    responseDTO.amount(new Money(paymentRequestDTO.getTransactionTotal()));
    Map<String, Object> additionalFields = paymentRequestDTO.getAdditionalFields();
    if (additionalFields != null) {
        if (additionalFields.containsKey("desiredOutcome")) {
            String desiredOutome = (String) additionalFields.get("desiredOutcome");
            if (desiredOutome.equals("SOFT DECLINE")) {
                responseDTO.successful(false);
                responseDTO.rawResponse("confirmation - failure - soft decline");
                responseDTO.responseMap(PaymentAdditionalFieldType.DECLINE_TYPE.getType(), PaymentDeclineType.SOFT.getType());
            } else if (desiredOutome.equals("HARD DECLINE")) {
                responseDTO.successful(false);
                responseDTO.rawResponse("confirmation - failure - hard decline");
                responseDTO.responseMap(PaymentAdditionalFieldType.DECLINE_TYPE.getType(), PaymentDeclineType.HARD.getType());
            }
        }
    } else {
        responseDTO.rawResponse("confirmation - success");
        responseDTO.successful(true);
    }
    return responseDTO;
}
Also used : Money(org.broadleafcommerce.common.money.Money) PaymentResponseDTO(org.broadleafcommerce.common.payment.dto.PaymentResponseDTO)

Example 5 with PaymentResponseDTO

use of org.broadleafcommerce.common.payment.dto.PaymentResponseDTO in project BroadleafCommerce by BroadleafCommerce.

the class NullIntegrationGatewayTransactionServiceImpl method commonCreditCardProcessing.

/**
 * Does minimal Credit Card Validation (luhn check and expiration date is after today).
 * Mimics the Response of a real Payment Gateway.
 */
protected PaymentResponseDTO commonCreditCardProcessing(PaymentRequestDTO requestDTO, PaymentTransactionType paymentTransactionType) {
    PaymentResponseDTO responseDTO = new PaymentResponseDTO(PaymentType.CREDIT_CARD, NullIntegrationGatewayType.NULL_INTEGRATION_GATEWAY);
    responseDTO.valid(true).paymentTransactionType(paymentTransactionType);
    CreditCardDTO creditCardDTO = requestDTO.getCreditCard();
    String transactionAmount = requestDTO.getTransactionTotal();
    CreditCardValidator visaValidator = new CreditCardValidator(CreditCardValidator.VISA);
    CreditCardValidator amexValidator = new CreditCardValidator(CreditCardValidator.AMEX);
    CreditCardValidator mcValidator = new CreditCardValidator(CreditCardValidator.MASTERCARD);
    CreditCardValidator discoverValidator = new CreditCardValidator(CreditCardValidator.DISCOVER);
    if (StringUtils.isNotBlank(transactionAmount) && StringUtils.isNotBlank(creditCardDTO.getCreditCardNum()) && (StringUtils.isNotBlank(creditCardDTO.getCreditCardExpDate()) || (StringUtils.isNotBlank(creditCardDTO.getCreditCardExpMonth()) && StringUtils.isNotBlank(creditCardDTO.getCreditCardExpYear())))) {
        boolean validCard = false;
        if (visaValidator.isValid(creditCardDTO.getCreditCardNum())) {
            validCard = true;
        } else if (amexValidator.isValid(creditCardDTO.getCreditCardNum())) {
            validCard = true;
        } else if (mcValidator.isValid(creditCardDTO.getCreditCardNum())) {
            validCard = true;
        } else if (discoverValidator.isValid(creditCardDTO.getCreditCardNum())) {
            validCard = true;
        }
        boolean validDateFormat = false;
        boolean validDate = false;
        String[] parsedDate = null;
        if (StringUtils.isNotBlank(creditCardDTO.getCreditCardExpDate())) {
            parsedDate = creditCardDTO.getCreditCardExpDate().split("/");
        } else {
            parsedDate = new String[2];
            parsedDate[0] = creditCardDTO.getCreditCardExpMonth();
            parsedDate[1] = creditCardDTO.getCreditCardExpYear();
        }
        if (parsedDate.length == 2) {
            String expMonth = parsedDate[0];
            String expYear = parsedDate[1];
            try {
                DateTime expirationDate = new DateTime(Integer.parseInt("20" + expYear), Integer.parseInt(expMonth), 1, 0, 0);
                expirationDate = expirationDate.dayOfMonth().withMaximumValue();
                validDate = expirationDate.isAfterNow();
                validDateFormat = true;
            } catch (Exception e) {
            // invalid date format
            }
        }
        if (!validDate || !validDateFormat) {
            responseDTO.amount(new Money(0)).rawResponse("cart.payment.expiration.invalid").successful(false);
        } else if (!validCard) {
            responseDTO.amount(new Money(0)).rawResponse("cart.payment.card.invalid").successful(false);
        } else {
            responseDTO.amount(new Money(requestDTO.getTransactionTotal())).rawResponse("Success!").successful(true);
        }
    } else {
        responseDTO.amount(new Money(0)).rawResponse("cart.payment.invalid").successful(false);
    }
    return responseDTO;
}
Also used : CreditCardValidator(org.apache.commons.validator.CreditCardValidator) CreditCardDTO(org.broadleafcommerce.common.payment.dto.CreditCardDTO) Money(org.broadleafcommerce.common.money.Money) PaymentResponseDTO(org.broadleafcommerce.common.payment.dto.PaymentResponseDTO) DateTime(org.joda.time.DateTime) PaymentException(org.broadleafcommerce.common.vendor.service.exception.PaymentException)

Aggregations

PaymentResponseDTO (org.broadleafcommerce.common.payment.dto.PaymentResponseDTO)14 Money (org.broadleafcommerce.common.money.Money)5 OrderPayment (org.broadleafcommerce.core.payment.domain.OrderPayment)5 ArrayList (java.util.ArrayList)4 PaymentException (org.broadleafcommerce.common.vendor.service.exception.PaymentException)4 PaymentTransaction (org.broadleafcommerce.core.payment.domain.PaymentTransaction)4 HashMap (java.util.HashMap)3 CheckoutException (org.broadleafcommerce.core.checkout.service.exception.CheckoutException)3 Order (org.broadleafcommerce.core.order.domain.Order)3 Address (org.broadleafcommerce.profile.core.domain.Address)3 PaymentRequestDTO (org.broadleafcommerce.common.payment.dto.PaymentRequestDTO)2 PaymentGatewayConfigurationService (org.broadleafcommerce.common.payment.service.PaymentGatewayConfigurationService)2 Collection (java.util.Collection)1 CreditCardValidator (org.apache.commons.validator.CreditCardValidator)1 PaymentGatewayType (org.broadleafcommerce.common.payment.PaymentGatewayType)1 PaymentTransactionType (org.broadleafcommerce.common.payment.PaymentTransactionType)1 CreditCardDTO (org.broadleafcommerce.common.payment.dto.CreditCardDTO)1 FulfillmentGroup (org.broadleafcommerce.core.order.domain.FulfillmentGroup)1 PricingException (org.broadleafcommerce.core.pricing.service.exception.PricingException)1 RollbackFailureException (org.broadleafcommerce.core.workflow.state.RollbackFailureException)1